JS Async Await
Await <–> Functions that return Promises
Async <–> Functions that CONTAINS Await functions
Await Functions <---> Promise-returning Functions
^ ^
| |
contains contains
| | Outer Functions <---> Async Functions
NOTE: await
can be used on Regular non-Promise returning Functions but it would do nothing.
- We can add
await
to non-promise returning function and wrap it around anasync
function BUT its stupid and pointless.- example below:
async function AsyncRegularFunction(msg,wtime){..
is the same asfunction RegularFunction
await RegularFunction("noPromiseSleep",1000)
call is same asRegularFunction("noPromiseSleep",1000)
call
- example below:
function PromiseFunction(msg,wtime) {
return new Promise(resolve => {
setTimeout(() => {
resolve(msg);
, wtime);
};
})
}
//No-promise Regular Function
function RegularFunction(msg,wtime){
setTimeout(() => {
console.log(msg)
return msg
, wtime);
}
}
async function AsyncPromiseFunction(msg,wtime){
console.log("inside AsyncPromiseFunction call")
return PromiseFunction(msg,wtime);
}
//AsyncRegularFunction is the same as RegularFunction
//Therefore the function below is a stupid function and should never be called or made
async function AsyncRegularFunction(msg,wtime){
console.log("inside AsyncRegularFunction call")
return RegularFunction(msg,wtime);
}
async function mainCall() {
console.log("start");
//`await RegularFunction` is same as `RegularFunction`
await RegularFunction("RegularFunction_noPromise",1000);
RegularFunction("RegularFunction_noPromise",1000);
console.log("done");
// expected output: "resolved"
}
mainCall();
1 Normal function behavior
- The theme is that typical functions(non-promise) in JS is not really predictable or truly sequential even though it may seem that way!!
function mainCall() {
console.log("start");
RegularFunction("RegularFunction_noPromise",2000);
console.log("done");
// expected output: "resolved"
}
> "start"
> "done"
delay 2s> "RegularFunction_noPromise"
- Watch that rather than sequentially blocking for the RegularFunction, it skips it and and runs
console.log("done");
.
2 With promise
2.1 always put await next to promise function call
- Do we put
await
outside ofconsole.log
or inside?- inside, right next to the function that returns a promise
async function mainCall() {
console.log("start");
console.log(await AsyncPromiseFunction("AsyncPromiseFunction",1000));
console.log("done");
}
> "start"
> "inside AsyncPromiseFunction call"
delay 2s> "AsyncPromiseFunction"
> "done"
async function mainCall() {
console.log("start");
await console.log(AsyncPromiseFunction("AsyncPromiseFunction",1000));
console.log("done");
}
> "start"
> "inside AsyncPromiseFunction call"
> [object Promise]
> "done"
2.2 Await blocks Everything that comes after
RegularFunction
comes BEFORE theconsole.log(await AsyncPromiseFunction("AsyncPromiseFunction",2000));
meaning theRegularFunction
does not get blocked.
Here are 2 different timings, but in both cases, RegularFunction
call and AsyncPromiseFunction
call runs as if they were independent.
async function mainCall() {
console.log("start");
RegularFunction("RegularFunction_noPromise",3000); //BEFORE the await does NOT get blocked
console.log(await AsyncPromiseFunction("AsyncPromiseFunction",2000));//AFTER the await gets blocked
console.log("done");//AFTER the await gets blocked
}
> "start"
> "inside AsyncPromiseFunction call"
2
delay > "AsyncPromiseFunction"
> "done"
~0.5 to 1
delay > "RegularFunction_noPromise"
async function mainCall() {
console.log("start");
RegularFunction("RegularFunction_noPromise",2000); //BEFORE the await does NOT get blocked
console.log(await AsyncPromiseFunction("AsyncPromiseFunction",3000));//AFTER the await gets blocked
console.log("done");//AFTER the await gets blocked
}
> "start"
> "inside AsyncPromiseFunction call"
2
delay > "RegularFunction_noPromise"
~0.5 to 1
delay > "AsyncPromiseFunction"
> "done"
When you mix regular function calls with properly made await
function calls, they behave as if running in parallel other wise the delay ~0.5 to 1
should be delay 3
- Here is the scenario where
RegularFunction
comes AFTER theconsole.log(await AsyncPromiseFunction("AsyncPromiseFunction",2000));
meaning theRegularFunction
does get blocked.
async function mainCall() {
console.log("start");
console.log(await AsyncPromiseFunction("AsyncPromiseFunction",2000));
RegularFunction("RegularFunction_noPromise",4000); //AFTER the await gets blocked
console.log("done"); //AFTER the await gets blocked
}
> "start"
> "inside AsyncPromiseFunction call"
2
delay > "AsyncPromiseFunction"
> "done"
4
delay > "RegularFunction_noPromise"
- Notice how the
await AsyncPromiseFunction
blocks ALL the code underneath it.- By this train of thought, to make code SORTA sequential, just use
await
on all the promise-function calls.- We say SORTA because notice in the code above, the result of
RegularFunction("RegularFunction_noPromise",4000);
andconsole.log("done");
switched places meaning we can’t control behavior of non-promise regular functions.(The motto of javascript)
- We say SORTA because notice in the code above, the result of
- By this train of thought, to make code SORTA sequential, just use
3 Sequential await
async function mainCall() {
console.log("start");
console.log(await AsyncPromiseFunction("AsyncPromiseFunctionA",2000));
console.log(await AsyncPromiseFunction("AsyncPromiseFunctionB",1000));
console.log(await AsyncPromiseFunction("AsyncPromiseFunctionC",3000));
console.log(await AsyncPromiseFunction("AsyncPromiseFunctionD",2000));
console.log("done");
}
> "start"
> "inside AsyncPromiseFunction call"
> "AsyncPromiseFunctionA"
> "inside AsyncPromiseFunction call"
> "AsyncPromiseFunctionB"
> "inside AsyncPromiseFunction call"
> "AsyncPromiseFunctionC"
> "inside AsyncPromiseFunction call"
> "AsyncPromiseFunctionD"
> "done"
4 Parallel
async function mainCall() {
console.log("start");
console.time('myClock')
= await Promise.all([
parallel AsyncPromiseFunction("AsyncPromiseFunctionA",6000),
AsyncPromiseFunction("AsyncPromiseFunctionB",1000),
AsyncPromiseFunction("AsyncPromiseFunctionC",3000),
AsyncPromiseFunction("AsyncPromiseFunctionD",2000),])
console.log(parallel);
console.timeEnd('myClock')
console.log("done");
}
> "start"
> "inside AsyncPromiseFunction call"
> "inside AsyncPromiseFunction call"
> "inside AsyncPromiseFunction call"
> "inside AsyncPromiseFunction call"
> ["AsyncPromiseFunctionA","AsyncPromiseFunctionB","AsyncPromiseFunctionC","AsyncPromiseFunctionD"]
> "myClock: 6001.09375 ms"
When ran in parallel, the execution time is only as long as the longest function which is AsyncPromiseFunction("AsyncPromiseFunctionA",6000)
5 Showcase stupid usage of async await with typical non-promise functions
would await AsyncRegularFunction("AsyncNoPromiseSleep",2000);
or await RegularFunction("AsyncNoPromiseSleep",2000);
or AsyncRegularFunction("AsyncNoPromiseSleep",2000);
do anything different? NO!!
async function mainCall() {
console.log("start");
RegularFunction("RegularFunction",2000);
console.log(await AsyncPromiseFunction("AsyncPromiseFunction",3000));
console.log("done");
}
> "start"
> "inside AsyncPromiseFunction call"
2
delay > "RegularFunction"
~0.5 to 1
delay > "AsyncPromiseFunction"
> "done"
async function mainCall() {
console.log("start");
await RegularFunction("RegularFunction",2000);
console.log(await AsyncPromiseFunction("AsyncPromiseFunction",3000));
console.log("done");
}
> "start"
> "inside AsyncPromiseFunction call"
2
delay > "RegularFunction"
~0.5 to 1
delay > "AsyncPromiseFunction"
> "done"
async function mainCall() {
console.log("start");
AsyncRegularFunction("AsyncRegularFunction",2000);
console.log(await AsyncPromiseFunction("AsyncPromiseFunction",3000));
console.log("done");
}
> "start"
> "inside AsyncRegularFunction call"
> "inside AsyncPromiseFunction call"
2
delay > "AsyncRegularFunction"
~0.5 to 1
delay > "AsyncPromiseFunction"
> "done"
async function mainCall() {
console.log("start");
await AsyncRegularFunction("AsyncRegularFunction",2000);
console.log(await AsyncPromiseFunction("AsyncPromiseFunction",3000));
console.log("done");
}
> "start"
> "inside AsyncRegularFunction call"
> "inside AsyncPromiseFunction call"
2
delay > "AsyncRegularFunction"
~0.5 to 1
delay > "AsyncPromiseFunction"
> "done"
The code above all return the same results and are functionally correct but the stupidity will confuse other developers.
REMEMBER TO STOP USING await with Non-promise functions