Aligatro
@Aligatro
Turn food and coffee into software...

Почему асинхронная функция работает иначе?

Помогите в понимании асинхронных функций в js. Я накидал простенький пример в котором по непонятной мне причине async функции внутри которых loop с разным количеством итераций выполняются одновременно, а не по порядку (сначала там где итераций меньше, после там где больше).
Пример кода.

Для примера вот тот же самый код но реализованный через задержку используя setTimeout, который работает правильно - https://jsfiddle.net/jrk7p3tx/

Оставлю это объяснение будущему себе:
Любая функция вызванная в основном потоке, будь то синхронная или возвращающая промис, будет этот самый поток блокировать до окончания её выполнения. Единственное что доступно разработчику, это возможность зашафлить стек вызова (например обернув в setTimeout) в котором сначала будут выполнены функции из основного потока, а после те которые придут из очереди событий от setTimeout.

В итоге получается что результаты при использования loop'ов "появляются одновременно", потому-что всё это время идёт блокирующая обработка циклов в основном потоке.
Во втором же примере setTimeout откладывает отправку простого объекта (а не исполнение блокирующего кода) плюс таймер крутится не в основном потоке, а в параллельном (webAPI). Что в итоге даёт эффект неблокирующего параллельного поведения.
  • Вопрос задан
  • 245 просмотров
Решения вопроса 1
0xD34F
@0xD34F Куратор тега JavaScript
выполняются одновременно

Всё-таки не одновременно. Поток выполнения один, так что... [разводит руками]

Из-за чего у вас возникла иллюзия "одновременности" - вы результат работы синхронного кода (*) решили получать асинхронно. Вызвали первый раз showText - цикл открутился, замечательно, но демонстрации результата пока не происходит, потому что await. Вот когда поток выполнения освободиться, тогда да. А до того - надо второй вызов showText выполнить. Ну а когда вызовы showText отработают - вот тогда их результаты и показываются, сразу все.

* Вы можете возразить - ...
...ну как же так, у меня там промис используется. А так. Недостаточно написать new Promise, чтобы получить желаемую асинхронность. Проведите небольшой эксперимент - откройте консоль, выполните

console.log('щас будем создавать промис');
new Promise(r => {
  console.log('создаём промис');
  setTimeout(() => {
    console.log('так, сейчас дёрнем резолв');
    r();
    console.log('резолв дёрнули');
  });
}).then(() => console.log('зарезолвились, наконец-то'));
console.log('промис создан');

и посмотрите на порядок вывода сообщений. Потом то же самое ещё раз, но без оборачивания резолва в setTimeout. Подумайте. Подумав, можно будет сделать очевидный вывод: а промисы-то - синхронны (да-да, вот так), код внутри промисов выполняется сразу после вызова конструктора. Асинхронным является получение результата.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@yarnstart
Превозмогание и React
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
summer Ярославль
от 100 000 до 140 000 ₽
КРАФТТЕК Санкт-Петербург
от 60 000 до 80 000 ₽
19 апр. 2024, в 22:48
100 руб./за проект
19 апр. 2024, в 20:43
20000 руб./за проект