MIT Weblab笔记 - Asynchronous Control

Introduction

  • Synchronous: Happening consecutively, one after another.
  • Asynchronous: Multiple processes can run at the same time.

Node.js

Node.js is an open-source, cross-platform JavaScript runtime environment that executes JavaScript code outside of a web browser.

  • Single-Threaded Event Loop: Unlike traditional multi-threaded servers that spawn a new thread for each client, Node.js uses a single-threaded event loop to manage all client connections. The Event Loop continuously checks the event queue to see if there are any events to be handled.
  • Non-blocking I/O: Node.js performs I/O operations (like reading from a database) asynchronously. Instead of waiting for the operation to complete, Node.js registers a callback and moves on to handle the next event. This non-blocking behavior ensures that Node.js can handle many I/O operations concurrently without getting bogged down by slow operations

.then()

syntax

1
2
const myStories = get('/api/stories');
setStories(myStories);
  • the get() function returns a promise.
  • myStories is a promise object immediately after this line runs. The promise represents an operation that hasn’t completed yet. JavaScript continues executing subsequent code without waiting for the promise to resolve.
  • setstories is called immediately with the promise myStories, not with the actual data that the promise will resolve to.

Correct handling:

1
2
3
4
5
get('/api/stories').then((stories) => {
setStories(stories);
}).catch((error) => {
console.log(error.message);
});

.then((stories) => { ... }) sets up a handler that waits for the promise to resolve.

  • If promise fulfilled, execute .then().
  • If promise rejected, execute .catch().

Async of promises

Promises let us keep running other code:

1
2
3
4
5
6
7
8
useEffect(() => {
get('/api/stories').then((stories) => {
setStories(stories);
})
console.log("do thing 1");
console.log("do thing 2");
console.log("do thing 3");
}, []);
  • These console.log statements execute synchronously, meaning they run immediately after the API request is initiated but before the promise resolves.
  • When the get function is called, it returns a promise and initiates the asynchronous operation to fetch data. JavaScript does not wait for this operation to complete. Instead, it continues executing the subsequent lines of code immediately. This is known as non-blocking behavior.

Handling multiple promises

1
2
3
4
5
6
7
8
9
10
11
12
13
const promise1 = get('/api/comments', { parent: parentId1 });
const promise2 = get('/api/comments', { parent: parentId2 });
const promise3 = get('/api/comments', { parent: parentId3 });
const promise4 = get('/api/comments', { parent: parentId4 });
const promise5 = get('/api/comments', { parent: parentId5 });

const promises = [promise1, promise2, promise3, promise4, promise5];

Promise.all(promises).then((allResults) => {
// allResults represent a list with the result of each promise
}).catch((err) => {
// Catch and report any error
});
  • Returns a promise that resolves to array of results of input promises
  • allResults represent a list with the result of each promise
1
2
3
4
5
Promise.race(promises).then((firstResult) => {
// Do something with the first result
}).catch((err) => {
// Catch and report any error
});
  • Return a single Promise
  • This returned promise settles as soon as any of the promises in the iterable (list in this example) settles (either fulfills or rejects).
1
2
3
4
5
Promise.any(promises).then((anyResult) => {
// Do something with the first fullfilled promise
}).catch((err) => {
// Catch and report any error
});
  • Return a sinfle Promise
  • This returned promise fulfills as soon as any of the promises in the iterable fulfills

await and async keywords

  • async function: declare a function to return a Promise.
  • Only asynchronous functions can use await. Asynchronous function is defined by async keyword. Asynchronous functions return control back to the caller before computation is done.
  • await waits for the promise to resolve and uses that value
1
2
3
4
5
6
7
8
9
10
11
const myFunction = async () => {
console.log('Start');
const data1 = await fetchData('url1');
console.log('Data 1:', data1);
const data2 = await fetchData('url2');
console.log('Data 2:', data2);
console.log('End');
}

myFunction();
console.log('After myFunction call');
  • When await is used, it pauses the execution of the async function until the awaited promise is resolved or rejected. This means that the lines of code following the await will not execute until the promise is settled. This “pause” is local to the async function where await is used.
  • While the async function is paused, the rest of the JavaScript (outside the specific function) code can continue to run, i.e., console.log('After myFunction call');. This means other tasks, events, and functions can continue to execute, keeping the overall program responsive.

MIT Weblab笔记 - Asynchronous Control
https://thiefcat.github.io/2024/07/15/MIT-Weblab/Async-Control/
Author
小贼猫
Posted on
July 15, 2024
Licensed under