«Серия вопросов для предварительного интервью 1» Заголовок сегодняшнего интервью и анализ идей

интервью

Эссе и вопрос интервью

Недавно была статья под названием"8 изображений, которые помогут вам увидеть порядок выполнения async/await и обещания шаг за шагом"Статья привлекла мое внимание.

Автор использовал предварительный вопрос интервью «Today's Toutiao» в 2017 году в качестве введения и шаг за шагом объяснил причины реализации окончательного результата. Он включает в себя множество понятий, таких как асинхронная последовательность выполнения, макро-задачи, микро-задачи и т. д. В то же время автор ограничивает область выполнения, которая подчиняется механизму цикла событий браузера. Вот исходный код:

async function async1 () {
    console.log('async1 start');
    await async2();
    console.log('async1 end');
}

async function async2 () {
    console.log('async2');
}

console.log('script start');

setTimeout(function () {
    console.log('setTimeout');
}, 0);

async1();

new Promise(function (resolve) {
    console.log('promise1');
    resolve();
}).then(function () {
    console.log('promise2');
});

console.log('script end');

Тогда автор дал ответ первым. И надеюсь, что читатели сначала испытают себя.

script start
async1 start
async2
promise1
script end
promise2
async1 end
setTimeout

Когда я прочитал этот вопрос, я сначала написал результат в соответствии с моим собственным пониманием.

script start
async1 start
async2
promise1
script end
async1 end
promise2
setTimeout

некоторые важные понятия

Здесь нам нужно кратко рассказать о концепции событийного цикла.

  • Javascript является однопоточным, и все синхронные задачи выполняются в основном потоке.
  • В дополнение к основному потоку существует также очередь задач. Всякий раз, когда асинхронная задача имеет результат, событие вставляется в очередь задач.
  • Когда все задачи в основном потоке будут выполнены, система «последовательно» прочитает события в очереди задач. Соответствующая асинхронная задача входит в основной поток и начинает выполняться.
  • Между асинхронными задачами будут отличия, поэтому приоритеты их выполнения тоже будут разными. Он грубо делится на микрозадачи (микрозадачи, такие как Promise, MutaionObserver и т. д.) и макрозадачи (макрозадачи, такие как setTimeout, setInterval, I/O и т. д.). В одном и том же цикле событий микрозадачи всегда выполняются раньше макрозадач.
  • Основной поток будет повторять вышеуказанные шаги до тех пор, пока не будут выполнены все задачи.

Кроме того, есть понятие async/await.

  • Асинхронную функцию можно понимать как синтаксический сахар функции-генератора.
  • Он основан на промисах и всегда используется с ожиданием.
  • await возвращает объект Promise или значение выражения.
  • Его цель — сделать асинхронные операции более элегантными и их можно записать как синхронные.

Мое понимание

Позвольте мне рассказать вам о моем понимании предмета.

  • Сначала из числа консолей будет выведено 8 строк результатов.
  • Взглянув еще раз на код, я увидел setTimeout, поэтому молча заполнил его в строке 8.
  • Рядом с setTimeout я увидел console.log('script start') и async1(), которые могут подтвердить, что они являются синхронными задачами и сначала будут выполняться в основном потоке. Итак, правильно заполните script start в строке 1 и заполните первую строку async1 start в методе async1 в строке 2.
  • Затем я столкнулся с ожиданием. Поймите это буквально, давайте подождем. Нужно дождаться возврата функции async2() и заблокировать код позади. Итак, строка 3 заполнена async2.
  • Честно говоря, await выполнено, и пришло время вывести console.log('async1 end'). Однако не забывайте, что ниже есть еще один промис.Обратите внимание, что при создании нового промиса код в его методе разрешения будет выполнен немедленно. Если бы не await async1(), promise1 мог бы быть поставлен в очередь раньше. Итак, теперь строка 4 заполнена promise1.
  • Далее выполняется задача синхронизации console.log('script end'). Строка 5 заполняется концом скрипта.
  • Есть также строки 6 и 7, оставленные незаполненными. Вспомните концепцию async/await, упомянутую выше, ее цель — сделать так, чтобы асинхронный код можно было написать как синхронный. Ну, я думаю, что console.log('async1 end') - это синхронная задача. Итак, строка 6 заполнена концом async1.
  • Наконец, логично заполнить promise2 в строке 7.

Отличие от ответа автора

Вернувшись назад и сравнив с ответом автора, я обнаружил, что есть проблема с порядком строк 6 и 7.

Я терпеливо читал статью и читал async1 end и promise2 несколько раз снова и снова, но я до сих пор не могу понять, почему в браузере Chrome promise2 будет выводиться до конца async1.

Затем, когда я увидел область комментариев, я обнаружил, что кто-то высказал те же сомнения.@rhinelПредлагаемый в его 72.0.3622.0 (официальная версия) dev (64-разрядный) хром, результатом исчерпания является конец async1 перед promise2.

Сразу же я подумал о возможности того, что спецификация JS может измениться в будущем. Итак, я попробовал это со своим собственным проектом реагирования (версия babel-loader в проекте — 7.1.5. Пресеты .babelrc установлены на stage-3), и результат соответствует моему пониманию. Текущая последняя версия chromeV71, здесь действительно проблема с порядком выполнения.

Итак, я также оставил сообщение автору в области комментариев и обсудил его. @rhinel наконец подтвердил, что на самом деле план улучшения, который прошел этот приказ, был выпущен совсем недавно.Более быстрые асинхронные функции и обещанияПодробно объясняется это улучшение и достигнутый эффект. Вскоре после этого автор также добавил результаты нашего обсуждения в конце своей статьи для справки читателю.

Суммировать

Наконец, я хочу сказать, что, хотя эта статья основана только на вопросе интервью, это процесс размышлений, обсуждения и проверки порядка выполнения браузеров. Но именно благодаря этим процессам может столкнуться больше идей, глубже понять концепции и прояснить нормы.

Если у меня будет возможность, я надеюсь, что у меня будет больше обменов с другими коллегами.

PS: Добро пожаловать, чтобы обратить внимание на мою общедоступную учетную запись «Super Brother Front-end Small Stack», чтобы обменяться идеями и технологиями.