Async function without await in JavaScript
JavascriptAsynchronousAsync AwaitJavascript Problem Overview
I have two functions, a
and b
, that are asynchronous, the former without await
and the latter with await
. They both log something to the console and return undefined
. After calling either of the function, I log another message and look if the message is written before or after executing the body of the function.
function someMath() {
for (let i = 0; i < 9000000; i++) { Math.sqrt(i**5) }
}
function timeout(n) {
return new Promise(cb => setTimeout(cb, n))
}
// ------------------------------------------------- a (no await)
async function a() {
someMath()
console.log('in a (no await)')
}
// ---------------------------------------------------- b (await)
async function b() {
await timeout(100)
console.log('in b (await)')
}
clear.onclick = console.clear
aButton.onclick = function() {
console.log('clicked on a button')
a()
console.log('after a (no await) call')
}
bButton.onclick = function() {
console.log('clicked on b button')
b()
console.log('after b (await) call')
}
<button id="aButton">test without await (a)</button>
<button id="bButton">test with await (b)</button>
<button id="clear">clear console</button>
If you launch test without await
, the function seems to work as if it was synchronous. But with await
, the messages are inverted as the function is executed asynchronously.
How does JavaScript execute async
functions when no await
keyword is present?
Real use case: I have an await
keyword which is conditionally executed, and I need to know if the function is executed synchronously or not in order to render my element:
async function initializeComponent(stuff) {
if (stuff === undefined)
stuff = await getStuff()
// Initialize
if (/* Context has been blocked */)
renderComponent() // Render again if stuff had to be loaded
}
initializeComponent()
renderComponent()
P.S: The title has the JavaScript keyword to avoid confusion with the same questions in other languages (i.e <https://stackoverflow.com/q/12016567/6320039>)</sub>
Javascript Solutions
Solution 1 - Javascript
> An async function can contain an await expression, that pauses the > execution of the async function and waits for the passed Promise's > resolution, and then resumes the async function's execution and > returns the resolved value.
As you assumed, if no await is present, the execution is not paused and your code will then be executed in a non-blocking manner.
Solution 2 - Javascript
Everything is synchronous until a JavaScript asynchronous function is executed. In using async-await, await
is asynchronous and everything after await is placed in the event queue. It is similar to .then()
.
To better explain, take this example:
function main() {
return new Promise( resolve => {
console.log(3);
resolve(4);
console.log(5);
});
}
async function f(){
console.log(2);
let r = await main();
console.log(r);
}
console.log(1);
f();
console.log(6);
As await
is asynchronous and the rest all is synchronous, including promise, thus the output is:
1
2
3
5
6
// Async happened, await for main()
4
Similar behavior of main()
is without promise too:
function main() {
console.log(3);
return 4;
}
async function f(){
console.log(2);
let r = await main();
console.log(r);
}
console.log(1);
f();
console.log(5);
Output:
1
2
3
5
// Asynchronous happened, await for main()
4
Just removing await
will make whole async
function synchronous which it is.
function main() {
console.log(3);
return 4;
}
async function f(){
console.log(2);
let r = main();
console.log(r);
}
console.log(1);
f();
console.log(5);
Output:
1
2
3
4
5
Solution 3 - Javascript
The function is executed the same with or without await
. What await
does is automatically wait for the promise that's returned by the function to be resolved.
await timeout(1000);
more code here;
is roughly equivalent to:
timeout(1000).then(function() {
more code here;
});
The async function
declaration simply makes the function automatically return a promise that's resolved when the function returns.
Solution 4 - Javascript
As other answers say/indicate: an async function
just runs on spot until it encounters an await
- if there is no await
, it runs completely.
What may be worth adding that async
unconditionally makes your result a Promise
. So if you return something, there is a difference already and you simply can not get the result without returning to the JS engine first (similarly to event handling):
async function four(){
console.log(" I am four");
return 4;
}
console.log(1);
let result=four();
console.log(2,"It is not four:",result,"Is it a promise ?", result instanceof Promise);
result.then(function(x){console.log(x,"(from then)");});
console.log(3);