Функции являются синхронными. Период.
То, что может быть асинхронным, - это (абстрактный) процесс / рабочий процесс.
Когда кто-то говорит, что функция является «асинхронной», на самом деле он означает, что результат будет доступен через некоторое время. ,Результат обернут в Обещание, которое является ручкой для ожидания. Но процесс все еще может быть синхронным. Посмотрите на этот пример:
function foo() {
return new Promise((res, rej) => {
console.log(1);
console.log(2);
res();
});
};
function test() {
foo();
console.log(3);
};
и результат всегда один и тот же:
> test();
1
2
3
, что означает, что каждая функция была вызвана одна за другой синхронно. И действительно, если вы обновите функцию foo
до:
function foo() {
return new Promise((res, rej) => {
while (true) {}
res();
});
};
, вы заметите, что console.log(3)
никогда не запускается. И поэтому наши foo
блоки навсегда!
Теперь взгляните на этот пример:
function test() {
Promise.resolve().then(function() {
console.log(1);
console.log(2);
});
console.log(3);
};
и обратите внимание на другой результат: 3 1 2
. Все эти функции синхронны , так почему порядок отличается? Потому что .then()
откладывает выполнение на некоторое более позднее время.
В общем: sync / async на самом деле не свойство функции, а скорее свойство рабочего процесса. И в вашем случае это синхронно.
Примечание: это усложняется, когда возникают исключения. Давайте изменим функцию foo
из первого примера:
function foo() {
return new Promise((res, rej) => {
throw 'myException';
});
};
function test() {
foo();
console.log(3);
};
и вызовем test()
. О, вау, теперь 3
стоит первым (кто-то может подумать, что его вообще не следует выполнять !!!), а неперехваченное исключение myException
- вторым. Почему? Потому что движок JavaScript откладывает обработку исключений. Не спрашивайте меня почему, я понятия не имею, но я уверен, что есть причина для этого ... как и для всего. ;)
Вывод: Обещания не делают вещи автоматически асинхронными и всегда await
или не используют .then()
с функцией, которая возвращает обещание (если вы не ниндзя).