Каков порядок выполнения асинхронных функций, если их несколько в одном потоке?
Я изучаю концепцию асинхронных функций в JavaScript. Я знаю, что JavaScript является однопоточным, а функции обратного вызова помещаются за синхронный исполняемый код в потоке. Эта статья объяснила довольно хорошо. https://www.sohamkamani.com/blog/2016/03/14/wrapping-your-head-around-async-programming/
Но статья не объяснила мне один вопрос: что если в коде есть несколько функций обратного вызова? Например, приведенный ниже код, каков порядок выполнения? Асинхронная функция 1 или асинхронная функция 2 выполняются первыми? Спасибо заранее!
var request = require('request');
// async function 1: take 200ms
request('http://sohamkamani.com', function (error, response, body) {
console.log(body);
})
// async function 2: take 100ms
request('http://facebook.com', function (error, response, body) {
console.log(body);
})
console.log('I come after the request');
2 ответа
Запросы будут выполняться в том порядке, в котором вы их закодировали. Запрос на http://sohamkamani.com
будет отправлен, затем запрос http://facebook.com
, Но вы не можете знать порядок обратных вызовов, потому что они будут выполняться только после ответа сервера, и вы не знаете, когда это произойдет.
Единственное, что вы точно знаете о выводе вашего кода, это то, что I come after the request
будет первым, что будет записано в консоль, что произойдет после того, как оба запроса будут отправлены, но до выполнения их обратных вызовов.
Исходя из того, как вы описали свои события, вот примерно, как все будет происходить. Важные понятия здесь включают асинхронную обработку, стек вызовов и очередь событий.
Ваш сценарий, мы назовем его
main.js
, будет добавлен в стек вызовов. Ваш стек вызовов теперь выглядит так:- main.js
main.js начинает выполняться. Первая строка добавляется в стек вызовов. Ваш стек вызовов теперь выглядит так:
- запрос (" http://sohamkamani.com/",...)
- main.js
Запрос выполняется и будет отслеживаться всякий раз, когда обратный вызов разрешается. Поскольку здесь делать больше нечего, он удаляется из стека вызовов. Итак, ваш стек вызовов теперь выглядит так:
- main.js
Следующая строка в
main.js
добавляется в стек вызовов.- запрос (" http://facebook.com/",...)
- main.js
Опять же, запрос выполняется и будет отслеживаться всякий раз, когда обратный вызов разрешен. Он удаляется из стека вызовов.
- main.js
Следующая строка добавляется в стек вызовов
- console.log("Я прихожу после запроса");
- main.js
Это может быть выполнено немедленно, и запрос будет отправлен на вашу консоль, чтобы записать это предложение. Ваш стек вызовов теперь выглядит так:
- main.js
main.js
сделано, его можно удалить из стека вызовов. Ваш стек вызовов теперь пуст.Запрос на Facebook разрешен через 100 мс. Функция обратного вызова
function (error, response, body) { ... }
добавляется в очередь событий. Вещи в очереди событий могут быть выполнены только после очистки стека вызовов.Ваш стек вызовов чист! Функция обратного вызова facebook добавляется в стек вызовов и выполняется. Журнал консоли отправлен. Функция обратного вызова удаляется из стека вызовов.
Через 200 мс sohamkamani.com разрешается, и его функция обратного вызова отправляется в очередь событий. Ваш стек вызовов чист! Функция обратного вызова добавляется в стек вызовов, выполняется и удаляется из стека вызовов.