предисловие
The last time, I have learned
[ПОСЛЕДНИЙ РАЗ] всегда был серией, которую я хотел написать, стремясь пережить интерфейс через накопление.
Это также для их собственных упущений и обмена технологиями.
Приветствуем всех, кто комментирует и указывает на Tucao.
Серия статей была впервые опубликована на официальном аккаунте [Full-stack Front-End Selection].Подробнее о авторском сборнике статей можно узнать на официальном аккаунте.Nealyang/personalBlog. Каталоги являются предварительными
выполнить и запустить
Сначала нам нужно объявить,JavaScript
Исполнение и эксплуатация - два разных понятия.Исполнение, как правило, зависит от среды,Напримерnode
, браузер,Ringo
Ждать,Механизм выполнения JavaScript в разных средах может быть разным. И сегодня мы собираемся обсудитьEvent Loop
то естьJavaScript
форма реализации. Итак, ниже мы разберемсяnode
способ исполнения.И работает, относится к движку синтаксического анализа JavaScript. Это унифицировано.
О JavaScript
В этой статье, под этим подзаголовком, нам нужно только иметь в виду предложение:JavaScript — это однопоточный язык,несмотря ни на чтоHTML5
вWeb-Worker
или в узлеcluster
«бумажные тигры» иcluster
Или связанные с управлением процессами. Здесь читатель обращает внимание на различие: процесс и поток.
теперь, когдаJavaScript
Является однопоточным языком, тогда будет проблема, весь код должен выполняться предложение за предложением. Точно так же, как мы стоим в очереди за едой в столовой, мы должны стоять в очереди один за другим, чтобы заказать и оплатить. Кто не успел, подождите~
Концепция кардинга
Прежде чем подробно объяснять механизм исполнения, давайте разберемсяJavaScript
Некоторые основные понятия о , чтобы, когда мы будем говорить об этом позже, каждый имел представление и общий план в своем сердце.
Цикл событий
Что такое цикл событий?
На самом деле это понятие все еще относительно расплывчато, потому что его необходимо объяснять в связи с рабочим механизмом.
JavaScript
иметь основной потокmain thread
и стек вызововcall-stack
Также называется стеком выполнения. Все задачи помещаются в стек вызовов для ожидания выполнения основного потока.
А пока давайте сначала поймем, что большой круг на картинке выше — это цикл событий! И этот круг ходит по кругу ~ То есть,JavaScript
изEvent Loop
Он сопровождается полным жизненным циклом файла исходного кода, пока текущийJavaScript
В процессе работы внутренний цикл будет продолжать цикл, чтобы найтиqueue
Которые могут быть выполненыtask
.
очередь задач
task
, это смысл задачи, тут мы понимаем что каждое утверждение это задача
console.log(1);
console.log(2);
Вышеупомянутое утверждение на самом деле может быть понято как дваtask
.
а такжеqueue
Ну, этоFIFO
Очередь!
такTask Queue
Это очередь, которая несет задачи. а такжеJavaScript
изEvent Loop
Просто продолжайте приходить сюда, чтобы найти этоqueue
, Спроси Еслиtask
может бежать бежать.
Синхронная задача (SyncTask), асинхронная задача (AsyncTask)
Грубо говоря, задача синхронизации — это код, который может выполняться сразу же при выполнении основного потока.,Например:
console.log('this is THE LAST TIME');
console.log('Nealyang');
Код выполняется вышеconsole
, соответствующий результат будет немедленно напечатан на консоли.
Так называемая асинхронная задача — это выполнение основного потока к этомуtask
когда,"Фу! Ты подожди, я не первый выступаю, так что после окончания я вернусь и так тебе ххх казнь«Заметьте, я выше сказал, чтоЖдать тебявыполнить.
если быть честным,Асинхронная задача заключается в том, что вы сначала выполняете другие задачи, а после того, как я закончу это xxx, затем вставляете синхронную задачу задачи в очередь задач, чтобы дождаться ее выполнения.
setTimeout(()=>{
console.log(2)
});
console.log(1);
Как и в приведенном выше коде,setTimeout
Является асинхронной задачей, когда основной поток для выполнения столкнулсяsetTimeout
Если выясняется, что это асинхронная задача, сначала регистрируется асинхронный обратный вызов, а затем выполняется следующий оператор.console.log(1)
, По истечении указанного выше времени ожидания асинхронной задачи выполнитеconsole.log(2)
. Конкретный механизм выполнения будет проанализирован позже.
- Основной поток выполняет весь код сверху вниз
- Синхронные задачи входят непосредственно в основной поток для выполнения, в то время как асинхронные задачи входят в
Event Table
и зарегистрируйте соответствующую функцию обратного вызова - После завершения асинхронной задачи
Event Table
переместит эту функцию вEvent Queue
- После выполнения основной задачи потока она будет выполняться из
Event Queue
Прочитайте задачу в середине и войдите в основной поток, чтобы выполнить ее. - цикл, как указано выше
Вышеуказанные действия непрерывно зацикливаются, что мы называем циклом событий (Event Loop
).
Мелкий измельчитель
ajax({
url:www.Nealyang.com,
data:prams,
success:() => {
console.log('请求成功!');
},
error:()=>{
console.log('请求失败~');
}
})
console.log('这是一个同步任务');
- Сначала запрос ajax отправляется на
Event Table
, соответственно зарегистрированыonError
а такжеonSuccess
Перезвоните. - Основной поток выполняет задачи синхронизации:
console.log('这是一个同步任务');
- Задача основного потока выполняется, см.
Event Queue
Есть ли задача для выполнения, вот постоянная проверка, пока основной потокtask queue
Нет задач для выполнения, основной поток ожидает здесь - После выполнения ajax будет вызвана функция обратного вызова
push
прибытьEvent Queue
. (Шаги 3 и 4 не по порядку) - Основной поток "наконец-то" дождался
Event Queue
внутриtask
Его можно выполнить, и будет выполнена соответствующая задача обратного вызова. - так туда и обратно.
Макрозадача, микрозадача
JavaScript
Задачи не только делятся на синхронные задачи и асинхронные задачи, но также делятся на макро задачи из другого измерения (MacroTask
) и микрозадачи (MicroTask
).
Скажи это первымMacroTask
, весь код синхронной задачиMacroTask
(Это не очень строго, как объяснено ниже),setTimeout
,setInterval
,I/O
,UI Rendering
и т.д. являются макро задачами.
MicroTask
, почему вышесказанное не является строгим, но я все же подчеркиваю, что все задачи синхронизацииMacroTask
, потому что нам нужно запомнить лишь несколькоMicroTask
Вот и все, исключай! все остальноеMacroTask
.MicroTask
включать:Process.nextTick
,Promise.then catch finally
(обратите внимание, я не имею в виду Обещание),MutationObserver
.
Цикл событий в среде браузера
Когда мы разобрались, какиеMicroTask
, в дополнение к тем другимMacroTask
После этого, какие задачи синхронные, а какие асинхронные, здесь нам следует хорошенько разобраться в механизме выполнения JavaScript.
Как упоминалось в начале, выполнение и операция различны, и выполнение должно различать среду. Итак, здесь мы будемEvent Loop
Введение разделено на две среды: браузер и Node.
Поместите изображение здания города первым! Если вы поняли смысл этой картинки, то поздравляю, вы можете напрямую читать среду NodeEvent Loop
Глава готова!
Setimeate, Setinterval
setTimeout
setTimeout
Как долго выполняется функция обратного вызова.setInterval
Это то, как часто выполняется этот обратный вызов.
let startTime = new Date().getTime();
setTimeout(()=>{
console.log(new Date().getTime()-startTime);
},1000);
Приведенный выше код, как следует из названия, должен ждать 1 с перед его выполнением.console
. Поместите его в браузер для выполнения, ОК, как хотите.
Но на этот раз мы обсуждаем механизм выполнения JavaScript, поэтому здесь нам предстоит обсудить следующий код:
let startTime = new Date().getTime();
console.log({startTime})
setTimeout(()=>{
console.log(`开始执行回调的相隔时差:${new Date().getTime()-startTime}`);
},1000);
for(let i = 0;i<40000;i++){
console.log(1)
}
Запуск, как указано выше,setTimeout
Функция обратного вызова будет выполнена только через 4,7 секунды!setTimeout
Задержка в 1 с была удалена:
let startTime = new Date().getTime();
console.log({startTime})
setTimeout(()=>{
console.log(`开始执行回调的相隔时差:${new Date().getTime()-startTime}`);
},0);
for(let i = 0;i<40000;i++){
console.log(1)
}
В результате все еще нужно подождать до 4,7 с, прежде чем выполнять обратный вызов setTimeout. Похоже, задержка после setTimeout не имеет никакого эффекта!
Фактически, говоря это, мы должны вернуться к блок-схеме выполнения JavaScript выше.
setTimeout
Вот простой асинхронник, разбираем пошагово выполнение вышеуказанного кода через приведенную выше диаграмму
- первый
JavaScript
Выполнять код сверху вниз - столкнуться с заявлением о назначении и первым
console.log({startTime})
соответственно какtask
, помещенный в стек немедленного выполнения для выполнения. - встретить
setTImeout
является асинхронной задачей, зарегистрируйте соответствующую функцию обратного вызова. (Асинхронная функция говорит вам, js, не волнуйтесь, я вызову функцию обратного вызова через 1 с:console.log(xxx)
помещатьTask Queue
середина) - Хорошо, в настоящее время JavaScript продолжает падать и сталкивается с 40 000 циклических задач. На самом деле, в это время вышеупомянутый обратный вызов уже находится в
Task Queue
бинго. - После того, как все задачи в стеке немедленного выполнения выполнены, оглянитесь назад.
Task Queue
В задаче обнаруживается, что в ней уже есть асинхронная задача обратного вызова, поэтому она выполняется.
провести аналогию
На самом деле это не просто таймаут, а любая асинхронность, например сетевые запросы.
Это как, я заканчиваю работу в шесть часов, так что я могу организовать свои собственные действия!
Затем соберите компьютер (синхронная задача), подобрать пакет (синхронная задача),Позвони своей девушке и скажи, приходи на ужин(Это должна быть асинхронная задача), и тут подруга сказала, что ты подождешь, я сначала накрашусь, и позвоню тебе, когда закончу рисовать.
Тогда я не могу просто ждать и заниматься другими делами, например, я исправлю ошибку, пожалуйста, дайте мне знать. В итоге сказала через час, что я накрасилась, пошли ужинать. нет! Моя ошибка еще не исправлена? Подожди. . . . На самом деле, в это время ваш один час макияжа или 5 минут макияжа не имеют смысла. . . Потому что мой брат будет пуст~~
Если мой баг решится за полчаса и других задач для выполнения нет, то просто ждите здесь! Должны ждать! Стоять рядом с! . Потом позвонила моя девушка, я закончил макияж, пойдем ужинать, так что ладно, мы только что закончили вашу просьбу или я бездействовал после тайм-аута, поэтому я должен был выполнить ее немедленно.
setInterval
законченныйsetTimeout
, и, конечно же, не может скучать по своему брату-близнецу:setInterval
. Для исполнительного листа,setInterval
Зарегистрированная функция будет размещена в указанное времяTask Queue
, если предыдущая задача занимает слишком много времени, ее также нужно подождать.
Здесь нужно сказать, что дляsetInterval(fn,ms)
Например, мы формулируем неxx ms
выполнить один разfn
, вообще-то нетxx ms
, там будетfn
ВойтиTask Queue
середина.Как только функция обратного вызова setIntervalfn
Если время выполнения превышает xx мс, то временной интервал вообще отсутствует.Внимательно вспомните послевкусие, так ли это?
Promise
оPromise
Использование , но я не буду вводить здесь слишком много, и я представлю его подробно позже, когда буду писать статью «[ПОСЛЕДНИЙ РАЗ] Тщательно понять асинхронность JavaScript». Здесь мы говорим только о механизме выполнения JavaScript.
Как указано выше,promise.then
,catch
а такжеfinally
принадлежатьMicroTask
. Основное отличие здесь — асинхронность. Прежде чем расширять описание, давайте объединим вышеперечисленное, а потом "передернем" разобраться.
Во избежание путаницы у новичков в это время мы временноЗабудьте об асинхронных задачах JavaScript!Назовем это задачей синхронизации, которая будет выполняться позже.
С указанными выше ограничениями мы можем сказать, что JavaScript выполняет каждое выражение (Task
), в настоящее время вы можете столкнуться только с задачами, которые будут выполняться немедленно, и задачами, которые будут выполняться позже. Для задачи, которая будет выполняться позже, она не будет выполнена сразу после того, как ее можно будет выполнить, вам нужно дождаться, пока js выполнит эту поездку.
другая аналогия
Это как сделать автобус, автобус не ждет людей, и кто-то остановится на маршруте автобуса (сельский автобус! модный знак остановки), но когда автобус приходит, ты говоришь водителю, у меня болит живот и хочется pull x~ В это время автобус вас ждать не будет. Вы можете только дождаться возвращения следующего автобуса после того, как закончите тянуть его (Дашанлы! Один автобус на один маршрут).
OK! Вы сделали. . . Дождитесь автобуса, он скоро приедет! Однако сразу сесть в машину нельзя, так как в это время передниеЕсть беременная женщина! Есть старик! И рожать детейВы должны позволить им сесть в автобус, тогда вы можете сесть в автобус!
А эти беременные женщины, старики, медведи и дети - легендарныеMicroTask Queue
, И сразу после того, как вы и ваши коллеги и друзья должны сесть в машину за ними.
Здесь у нас нет понятия асинхронности, только возвращается тот же цикл.Есть два вида команд.Та команда, которая садится в автобус первой, называетсяMicroTask Queue
, а команда, сформированная вами и вашими коллегами, называется макрокомандой (MacroTask Queue
).
Понимание одного предложения: после возврата цикла событий начните выполнятьTask Queue
серединаtask
, но вотtask
имеютприоритет. Так что в приоритетеMicroTask Queue
задачи в
, выполнить после выполненияMacroTask Queue
задачи в
Мелкий измельчитель
Теория закончилась, и я не знаю, понял ты ее или нет. Давай, это промежуточные экзамены!
console.log('script start');
setTimeout(function() {
console.log('setTimeout');
}, 0);
Promise.resolve().then(function() {
console.log('promise1');
}).then(function() {
console.log('promise2');
});
Нет необходимости добавлять промис в setTimeout, и в промисе есть пример всего setTimeout. Потому что, пока вы понимаете приведенный выше код, это не более чем очередная поездка на автобусе!
Если вы так много сказали и все еще не можете понять картинку выше, то ответьте на [1] в официальном аккаунте и прикоснитесь к своей руке для руководства!
Цикл событий в среде узла
в узлеEvent Loop
основывается наlibuv
понял, иlibuv
— это новый кроссплатформенный уровень абстракции Node,libuv
Используя асинхронное, управляемое событиями программирование, ядро должно предоставитьi/o
Цикл событий и асинхронные обратные вызовы.libuv
изAPI
Включает синхронизацию, неблокирующую сеть, асинхронные операции с файлами, дочерние процессы и многое другое.
Цикл событий находится вlibuv
реализовано в. Итак, о узлеEvent Loop
Чтобы учиться, есть два официальных способа учиться:
- документация по libuv
- Официальный сайтWhat is the Event Loop?.
В среде обучения NodeEvent Loop
Прежде чем мы должны сначала прояснить среду выполнения, Node и цикл событий браузера — это две четко различающиеся вещи, и их нельзя путать. Событие nodejs основано на libuv, а цикл обработки событий браузера четко определен в спецификации html5.
┌───────────────────────────┐
┌─>│ timers │
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
│ │ pending callbacks │
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
│ │ idle, prepare │
│ └─────────────┬─────────────┘ ┌───────────────┐
│ ┌─────────────┴─────────────┐ │ incoming: │
│ │ poll │<─────┤ connections, │
│ └─────────────┬─────────────┘ │ data, etc. │
│ ┌─────────────┴─────────────┐ └───────────────┘
│ │ check │
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
└──┤ close callbacks │
└───────────────────────────┘
Цикл событий Node разделен на 6 этапов:
- таймеры: выполнить
setTimeout()
а такжеsetInterval()
Обратный вызов, срок действия которого истекает через . - ожидающий обратный вызов: есть несколько в предыдущем цикле
I/O
Обратный вызов будет отложен до тех пор, пока этот этап раунда не будет выполнен. - бездействие, подготовка: только для внутреннего использования
- опрос: самый важный этап, выполнение
I/O
обратный звонок, впри правильных условияхзаблокирует на этом этапе - проверить: выполнить
setImmediate
Перезвоните - закрыть обратные вызовы: выполнить
close
обратный вызов события, например.socket.on('close'[,fn])
,http.server.on('close, fn)
Ни один из шести вышеперечисленных этапов не включает process.nextTick() (описано ниже).
Общие механизмы реализации, показанные выше, у нас есть следующее конкретное описание каждого этапа развертывания.
этап таймеров
Фаза таймеров будет выполнятьсяsetTimeout
а такжеsetInterval
Обратный вызов и контролируется фазой опроса.
На этапе таймеров фактически используется минимальная куча вместо очереди для хранения всех элементов, что на самом деле понятно, потому что обратный вызов тайм-аута вызывается в порядке времени тайм-аута, а не очереди «первым поступил — первым обслужен». логика). И почему этап таймера находится на первой лестнице исполнения, на самом деле нетрудно понять. Время, указанное таймером в Node, также неточное, и таким образом оно может быть максимально точным, а его функция обратного вызова может быть выполнена как можно быстрее.
Ниже приведен пример с официального сайта:
const fs = require('fs');
function someAsyncOperation(callback) {
// Assume this takes 95ms to complete
fs.readFile('/path/to/file', callback);
}
const timeoutScheduled = Date.now();
setTimeout(() => {
const delay = Date.now() - timeoutScheduled;
console.log(`${delay}ms have passed since I was scheduled`);
}, 100);
// do someAsyncOperation which takes 95 ms to complete
someAsyncOperation(() => {
const startCallback = Date.now();
// do something that will take 10ms...
while (Date.now() - startCallback < 10) {
// do nothing
}
});
При входе в цикл события имеет воздушную очередь (fs.readFile()
Еще не завершено), таким образом, оставшееся количество миллисекунд для ожидания таймера, когда он достигнет 95 мс,fs.readFile()
Обратный вызов, который завершает чтение файла и занимает 10 мс, добавляется в очередь опроса и выполняется.
Когда обратный вызов завершается, в очереди больше нет обратных вызовов, поэтому цикл событий увидит, что пороговое значение для самого быстрого таймера достигнуто, а затем вернется к фазе таймеров, чтобы выполнить обратный вызов таймера. В этом примере вы увидите, что общая задержка между запланированным таймером и выполнением обратного вызова составит 105 мс.
этап ожидающих обратных вызовов
Стадия ожидающих обратных вызовов на самом делеI/O
Этап обратного звонка. Например, некоторые обратные вызовы ошибок TCP и т. д.
Возьми каштан: еслиTCP socket ECONNREFUSED
пытающийсяconnect
Времяreceives
, некоторые системы *nix хотят дождаться сообщения об ошибке. Это будет выполнено на этапе ожидающих обратных вызовов.
этап опроса
Этап опроса выполняет две основные функции:
- воплощать в жизнь
I/O
Перезвоните - Обработка событий в очереди опроса
Когда цикл обработки событий входит в фазу опроса, а в фазе таймеров нет исполняемой задачи (то есть нет обратного вызова таймера), возможны следующие две ситуации.
- Если очередь опроса не пуста, цикл обработки событий будет выполнять их до тех пор, пока она не станет пустой или не достигнет системно-зависимого (системно-зависимого предела)
- Если очередь опроса пуста, происходит одно из следующего
- Если у setImmediate() есть обратный вызов, который нужно выполнить, он немедленно перейдет к фазе проверки.
- И наоборот, если нет setImmediate() для выполнения, фаза опроса будет ждать добавления обратного вызова в очередь перед немедленным выполнением, поэтому мы говорим, что фаза опроса может блокироваться.
Как только очередь опроса пуста, цикл обработки событий возвращается к проверке задач в фазе таймера. Если есть, он вернется к фазе таймера для выполнения обратного вызова.
этап проверки
Этап проверки следует за этапом опроса,setImmediate()
Обратный вызов будет добавлен в очередь проверки, он используетсяlibuv API
специальный счетчик.
Обычно, когда код выполняется, цикл событий в конечном итоге достигает этапа опроса, а затем ожидает входящих ссылок или запросов и т. д., но если был указан setImmediate() и этап опроса в это время бездействует, этап опроса будет прервано Затем начните выполнение фазы проверки.
закрыть этап обратных вызовов
Если сокет или обработчик событий внезапно закрываются/прерываются (например:socket.destroy()
), то этот этап будет происходитьclose
обратный вызов выполняется. Иначе он пройдетprocess.nextTick()
проблема.
setImmediate() vs setTimeout()
setImmediate()
а такжеsetTimeout()
Очень похоже, разница зависит от того, кто его назвал.
-
setImmediate
Выполняется после фазы опроса, то есть фазы проверки -
setTimeout
Выполняется при бездействии опроса и при наступлении установленного времени в фазе таймера
Порядок, в котором выполняются таймеры, зависит от контекста, в котором они вызываются. Если оба вызываются из основного модуля, время будет ограничено производительностью процесса.
Например, если мы запустим следующее безI / O
script внутри цикла (т.е. основного модуля), порядок выполнения двух таймеров не определен, поскольку он ограничен производительностью процесса:
// timeout_vs_immediate.js
setTimeout(() => {
console.log('timeout');
}, 0);
setImmediate(() => {
console.log('immediate');
});
$ node timeout_vs_immediate.js
timeout
immediate
$ node timeout_vs_immediate.js
immediate
timeout
если вI/O
При перемещении этих двух вызовов внутри цикла всегда сначала выполняется немедленный обратный вызов:
// timeout_vs_immediate.js
const fs = require('fs');
fs.readFile(__filename, () => {
setTimeout(() => {
console.log('timeout');
}, 0);
setImmediate(() => {
console.log('immediate');
});
});
$ node timeout_vs_immediate.js
immediate
timeout
$ node timeout_vs_immediate.js
immediate
timeout
Так сsetTimeout()
по сравнению с использованиемsetImmediate()
Основное преимущество состоит в том, что еслиI / O
любые таймеры, запланированные в течение периода, затемsetImmediate()
Всегда будет выполняться перед любыми таймерами, независимо от того, сколько таймеров существует.
nextTick queue
может быть, вы заметилиprocess.nextTick()
Не показано на диаграмме, несмотря на то, что это часть асинхронного API. Так что у него своя очередь:nextTickQueue
.
Это потому чтоprocess.nextTick()
Технически не является частью цикла событий. Вместо этого будет обрабатываться после завершения текущей операции, независимо от текущей фазы текущего цикла событий.nextTickQueue
.
если он существуетnextTickQueue
, он очистит все функции обратного вызова в очереди и будет иметь приоритет над другимиmicrotask
воплощать в жизнь.
setTimeout(() => {
console.log('timer1')
Promise.resolve().then(function() {
console.log('promise1')
})
}, 0)
process.nextTick(() => {
console.log('nextTick')
process.nextTick(() => {
console.log('nextTick')
process.nextTick(() => {
console.log('nextTick')
process.nextTick(() => {
console.log('nextTick')
})
})
})
})
// nextTick=>nextTick=>nextTick=>nextTick=>timer1=>promise1
process.nextTick() vs setImmediate()
С точки зрения пользователя эти два имени очень запутанны.
-
process.nextTick()
Сразу на том же этапе -
setImmediate()
Запускается на следующей итерации или «тике» цикла событий
Кажется, что эти два имени должны называться под! Действительно~ чиновник тоже так думает. Но они говорят, что это исторический багаж, который не изменится.
По-прежнему рекомендуется использовать setImmediate как можно чаще. Потому что это делает программу управляемой и простой для понимания.
Зачем тебе еще нужноprocess.nextTick
, разумно. Рекомендуется ознакомиться с официальной документацией здесь:why-use-process-nexttick.
Разница между узлом и циклом событий браузера
Он резюмирует это в одном предложении:В среде браузера очередь задач микрозадачи выполняется после выполнения каждой макрозадачи. В Node.js микрозадача будет выполняться между различными этапами цикла событий, то есть после выполнения этапа будут выполняться задачи очереди микрозадач.
На фото выше лодка в волнах.
наконец
Приходи~ Последний экзамен
console.log('1');
setTimeout(function() {
console.log('2');
process.nextTick(function() {
console.log('3');
})
new Promise(function(resolve) {
console.log('4');
resolve();
}).then(function() {
console.log('5')
})
})
process.nextTick(function() {
console.log('6');
})
new Promise(function(resolve) {
console.log('7');
resolve();
}).then(function() {
console.log('8')
})
setTimeout(function() {
console.log('9');
process.nextTick(function() {
console.log('10');
})
new Promise(function(resolve) {
console.log('11');
resolve();
}).then(function() {
console.log('12')
})
})
Оставьте свой ответ в комментариях~~Старое железо!
использованная литература
- Tasks, microtasks, queues and schedules
- документация по libuv
- The Node.js Event Loop, Timers, and process.nextTick()
- официальный сайт узла
- Результаты выполнения async/await в среде chrome и среде node несовместимы, решить?
- Более быстрые асинхронные функции и обещания
- Понимание цикла событий за раз (тщательно решайте такие вопросы интервью)
- На этот раз досконально изучите механизм выполнения JavaScript.
- Не путайте nodejs и цикл событий в браузере
учеба по обмену
Обратите внимание на официальный аккаунт: [Full-stack front-end selection] Получайте хорошие рекомендации статей каждый день.
Ответьте на [1] в официальном аккаунте, присоединитесь к группе полного обучения интерфейсу и общайтесь вместе.