Вот мой код:
Код: Выделить всё
console.log("Start");
setTimeout(() => {
console.log("Async task1");
}, 2000);
setTimeout(() => {
console.log("Async task2");
}, 1000);
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(response => response.json())
.then(json => console.log("Fetched data:", json));
console.log("End");
Добавил точки останова в каждой строке и использовал переход с обходом (F10).
Наблюдал результат с быстрым и медленным шагом.
Протестировал тот же код в браузерах других разработчиков.
Ожидаемый результат
Код: Выделить всё
Start
End
Fetched data: { ... }
Async task2
Async task1
Обещание выборки выполняется следующим (микрозадача).
Обратные вызовы setTimeout выполняются последними (макрозадачи, в порядке таймера).
Что на самом деле происходит
При шаге быстро, порядок вывода соответствует ожидаемому.
При медленном шаге (пауза в несколько секунд между шагами) порядок вывода меняется.
Иногда Async Task1 появляется перед Async Task2 или выборка выполняется в другом порядке.
Другие разработчики не видят этой проблемы.
Порядок вывода меняется в зависимости от того, как долго я делаю паузу перед нажатием «Перешагнуть».
Иногда печатает:
Код: Выделить всё
Start
End
Async task1
Async task2
Fetched data: { ... }
Приостановка работы отладчика останавливает только основной поток JS.
Таймеры (setTimeout) и обещания (fetch) продолжают работать в фоновом режиме.
К моменту возобновления работы асинхронные задачи могут уже истекнуть, поэтому цикл событий выполняет их немедленно — это меняет порядок вывода.
Микрозадачи (промисы) всегда выполняются раньше макрозадач (таймеров), что влияет на порядок.
Вопросы
Почему приостановка работы отладчика меняет порядок выполнения асинхронных задач?
Как я могу отлаживать асинхронные задачи? код последовательно, чтобы обратные вызовы setTimeout и fetch выполнялись каждый раз в одном и том же порядке?
Существуют ли настройки или методы DevTools, позволяющие сделать отладку предсказуемой для асинхронного JavaScript?
Среда
Браузер: Google Chrome (последняя версия)
Инструменты разработчика: вкладка «Источники»
ОС: Windows 10
Язык: Vanilla JavaScript
Что вы пробовали?
Я добавил точки останова в каждую строку в Chrome DevTools и использовал кнопку «Шаг вперед (F10)» для построчной отладки. Я также протестировал тот же код в браузерах других разработчиков. Я делал паузы между шагами на разную продолжительность, чтобы наблюдать за результатом.
Чего вы ожидали?
Я ожидал, что сначала появятся синхронные журналы («Начало» и «Конец»), затем результат обещания выборки и, наконец, обратные вызовы setTimeout в порядке их таймеров. Ожидаемый результат:
Код: Выделить всё
Start
End
Fetched data: { ... }
Async task2
Async task1
Когда я медленно вошел в отладчик, порядок изменился. Иногда «Асинхронная задача 1» появлялась перед «Асинхронной задачей 2» или даже до результата выборки. Порядок вывода зависел от того, как долго я делал паузу между шагами. Другие разработчики не заметили этой проблемы.
Подробнее здесь: https://stackoverflow.com/questions/797 ... owly-in-ch
Мобильная версия