Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Async function without await in JavaScript

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 Using async without await)

like image 515
Ulysse BN Avatar asked Aug 09 '17 15:08

Ulysse BN


People also ask

Can function be async without await JavaScript?

In this way, an async function without an await expression will run synchronously. If there is an await expression inside the function body, however, the async function will always complete asynchronously. Code after each await expression can be thought of as existing in a .then callback.

Can we write async method without await?

The current method calls an async method that returns a Task or a Task<TResult> and doesn't apply the Await operator to the result. The call to the async method starts an asynchronous task. However, because no Await operator is applied, the program continues without waiting for the task to complete.

Is await required in async function?

There's no specific need to mark a function async unless you specifically need one of the benefits of an async function such as the ability to use await inside that function or the automatic error handling it provides.

Can we use async await without promise?

This rule applies when the await operator is used on a non-Promise value. await operator pauses the execution of the current async function until the operand Promise is resolved.


2 Answers

Mozilla documentation:

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.

like image 128
Karim Avatar answered Sep 17 '22 11:09

Karim


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 
like image 43
NAVIN Avatar answered Sep 20 '22 11:09

NAVIN