Функция Async без ожидания в Javascript

У меня есть две функции a и b которые являются асинхронными: первая без await а вторая с await. Они оба что-то записывают в консоль и возвращают undefined. После вызова любой функции я регистрирую другое сообщение и проверяю, написано ли это сообщение до или после выполнения тела функции.

function someMath() {
  for (let i = 0; i < 3000000; 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() {
  a()
  console.log('after a (no await) call')
}

bButton.onclick = function() {
  b()
  console.log('after b (await) call')
}
<button id="aButton">test without await</button>
<button id="bButton">test with await</button>
<button id="clear">clear console</button>

Ответы

Ответ 1

из Mozilla Doc:

Асинхронная функция может содержать выражение await, которое приостанавливает выполнение асинхронной функции и ожидает разрешения переданной Promise, а затем возобновляет выполнение асинхронной функции и возвращает разрешенное значение.

Как вы и предполагали, если ожидание отсутствует, выполнение не приостанавливается, и ваш код будет выполняться синхронно.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function#Description

Ответ 2

Все происходит синхронно, пока не будет выполнена асинхронная функция Javascript. При использовании async-await await является асинхронным, и все, что находится после await, помещается в очередь событий. Аналогично .then().

Чтобы лучше объяснить, возьмите этот пример:

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);

Поскольку await является асинхронным, а остальные все синхронны, включая обещание, таким образом, вывод

1
2
3
5
6
// Async happened, await for main()
4

Подобное поведение main() тоже не обещает:

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);

Выход:

1
2
3
5
// Asynchronous happened, await for main()
4

Простое удаление await сделает всю async функцию синхронной.

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);

Выход:

1
2
3
4
5

Ответ 3

Функция выполняется так же или без await. То, что await, автоматически ожидает ожидания, возвращаемого функцией, которую нужно решить.

await timeout(1000);
more code here;

примерно эквивалентно:

timeout(1000).then(function() {
    more code here;
});

Объявление async function просто заставляет функцию автоматически возвращать обещание, которое разрешается при возврате функции.