I have two async
functions. Both of them are waiting for two 3 seconds function calls. But the second one is faster than the first. I think the faster one is running in parallel and other in serial. Is my assumption correct? If yes, why is this happening as both the functions look logically same?
function sleep() {
return new Promise(resolve => {
setTimeout(resolve, 3000);
});
}
async function serial() {
await sleep();
await sleep();
}
async function parallel() {
var a = sleep();
var b = sleep();
await a;
await b;
}
serial().then(() => {
console.log("6 seconds over");
});
parallel().then(() => {
console.log("3 seconds over");
});
Serial Run: Run the functions one after another
// 🚫 It’s slow! and use only for serial(one after another) run
async function doThings() {
const thing1 = await asyncThing1(); // waits until resolved/rejected
console.log(thing1);
const thing2 = await asyncThing2(); // starts only after asyncThing1() has finished.
console.log(thing2);
}
doThings();
Parallel Run: Run the functions parallel
// ✅ async code is run in parallel!
async function doThings() {
const p1 = asyncThing1(); // runs parallel
const p2 = asyncThing2(); // runs parallel
// Method 1: Prefer => Promise.all()
const [resultThing1, resultThing2] = await Promise.all([p1, p2]); // waits for all
// the promises get resolved or fails fast (If one of the promises supplied to it
// rejects, then the entire thing rejects).
// Method 2: Not-Preferred
const resultThing1 = await p1;
const resultThing2 = await p2;
console.log(resultThing1); // reaches here only after both the p1 & p2 have completed.
console.log(resultThing2);
}
doThings();
Frxstream already has an excellent answer. To build on that, and provide some perspective:
The first thing to recognize is that Promises are created "hot" - that is, by the time you have a promise object, it is already "in progress".
The second important concept is that await
is like an "asynchronous wait" - that is, it pauses the execution of the function until that promise completes.
So, the serial
function calls sleep
, gets a promise back, and then (asynchronously) waits for that promise to complete. After that promise completes 3 seconds later, serial
again calls sleep
, gets a promise back, and then (asynchronously) waits for that promise to complete. After that promise completes 3 seconds later, serial
completes.
The parallel
function calls sleep
and stores its promise in a
, and then calls sleep
and stores its promise in b
, and then (asynchronously) waits for a
to complete. After a
completes 3 seconds later, parallel
(asynchronously) waits for b
to complete. After b
completes practically immediately, parallel
completes.
It's clearer if you write your serial
function like this:
async function serial() {
var a = sleep(); //
await a; // await sleep();
var b = sleep(); //
await b; // await sleep();
}
async function parallel() {
var a = sleep();
var b = sleep();
await a;
await b;
}
Here you can clearly see that in the serial
function, the second sleep()
is only called after the first sleep()
has completed, while in parallel
it's called immediately, before the first has completed, and then it waits for both to complete. So while they may look functionally identical, they are subtly different.
Because thesleep()
function is a synchronous function, it just return a asynchronous promise, eg:
function sleep (time) {
return new Promise((resolve) => setTimeout(resolve, time));
}
In parallel()
, the two sleep()
synchronously init two promise,they wait to be resolved meanwhile, it's going to be about 3s.
However, in serial()
, the two await sleep()
means that the second sleep()
promise must wait for the first sleep()
to be resolved, so it's going to be about 6s.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With