Функция 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
просто заставляет функцию автоматически возвращать обещание, которое разрешается при возврате функции.