6

From MDN

Asynchronous functions operate in a separate order than the rest of the code via the event loop,

However I don't understand what that means for a simple function that doesn't return anything explicitly and doesn't use await at all. Is it in any way useful to declare a function async in this case? Would it be executed at a later time to allow the page to respond for example while it executes? My test shows it's executed synchronously and doesn't defer at all:

async function foo() {
  console.log('Start heavy stuff');
  for (let i = 0; i < 90000000; ++i) {
    Math.random()
  }
  console.log('Fnish heavy stuff')
}

foo();
console.log('All done, synchronously');

The logs are shown in the expecterd order, so could there be a use to making this function async in this case? Is this in any way similar to calling this function with a setTimeout(foo, 0)?

Code Maniac
  • 37,143
  • 5
  • 39
  • 60
George
  • 181
  • 5

2 Answers2

7

async functions run synchronously until the first await or return is reached, an error is thrown, or the code execution just runs off the end of the function (as it does in your function). At that point, the function returns a promise.

Is it in any way useful to declare a function async in this case?

Not in that specific case, no. There doesn't seem to be any reason for the function to return a promise, and all of its work is done synchronously as you saw in your test.

Would it be executed at a later time to allow the page to respond for example while it executes?

No.

There isn't really a good reason to declare a function async when it doesn't use await. It makes it return a promise, but doesn't do anything else other than that. Maybe if you were going to use it in a promise chain, but...

Here's a slightly different example of how the async function runs synchronously:

async function example1() {
    console.log("this is done synchronously");
    await Promise.resolve();
    console.log("this is done asynchronously");
}

console.log("before calling example1");
example1().then(() => {
    console.log("promise from example1 was fulfilled");
});
console.log("after calling example1");

That outputs:

before calling example1
this is done synchronously
after calling example1
this is done asynchronously
promise from example1 was fulfilled
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • very well written answer. +1, i guess this can be moved to the dupe target. :) – Code Maniac Apr 09 '20 at 11:05
  • @CodeManiac - Thanks. I should have known there was a good dupetarget. I think this is worded specifically enough to this question that I'll leave it here, but... – T.J. Crowder Apr 09 '20 at 11:19
4

No, synchronous code like the "heavy" Math.random() loop in your example won't run any differently.

However, the difference is that constructing something like this, which lets other code run, is near-trivial with async functions, since all the heavy lifting to make this a coroutine/generator/... happens during transpilation or in the runtime.

function delay(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

// or maybe:

function continueSoon() {
  return new Promise((resolve) => setImmediate(resolve));
}

async function foo() {
  console.log("Start heavy stuff");
  for (let i = 0; i < 90000000; ++i) {
    Math.random();
    if(i % 10000 == 0) await delay(10);
  }
  console.log("Fnish heavy stuff");
}
AKX
  • 152,115
  • 15
  • 115
  • 172