Насколько я понимаю, обещание - это то, что может разрешить () или отклонить (), но я был удивлен, обнаружив, что код в обещании продолжает выполняться после вызова решения или отклонения.
Я считал, что функция resolve или reject является асинхронной версией exit или return, которая остановит все немедленное выполнение функций.
Может ли кто-нибудь объяснить, почему в следующем примере иногда отображается console.log после вызова разрешения:
var call = function() {
return new Promise(function(resolve, reject) {
resolve();
console.log("Doing more stuff, should not be visible after a resolve!");
});
};
call().then(function() {
console.log("resolved");
});
javascript
promise
ecmascript-6
es6-promise
Людвиг ван Бетховен
источник
источник
resolve()
не является оператором управления JS, который волшебным образом мог бы иметь эффектreturn
, это просто вызов функции, и да, выполнение продолжается после него.Ответы:
В JavaScript есть концепция «выполнить до завершения» . Если не возникает ошибка, функция выполняется до тех пор, пока не будет достигнут
return
оператор или его конец. Другой код вне функции не может этому помешать (если, опять же, не возникнет ошибка).Если вы хотите
resolve()
выйти из функции инициализатора, вы должны добавить ееreturn
:return new Promise(function(resolve, reject) { return resolve(); console.log("Not doing more stuff after a return statement"); });
источник
resolve()
- это асинхронная функция. Как мы видели в другом (удаленном) ответе, некоторые люди считают, что при вызовеresolve
немедленно запускаются любые обратные вызовы.resolve
Сам @Alnitak не асинхронен, а полностью синхронен. Несмотря на то, что используется строго ES6 API, невозможно наблюдать, синхронный он или асинхронный.resolve
приведет к немедленному вызову любых зарегистрированных обратных вызовов, так что они будут частью текущего стека вызовов. Это неправда, вместо этого он просто ставит в очередь обратные вызовы (и вы правы, это не асинхронно, но он просто выполняет свою задачу и немедленно завершает работу)console.log
вместо «почему» появляется в таком порядке. Пока что то, чтоresolve
делает и как обещает, не имеет отношения к тому, как я интерпретирую вопрос. Но, конечно, это все же важно знать в контексте обещаний. Одна из причин, по которой я проголосовал за ваш ответ :)Обратные вызовы, которые будут вызываться при
resolve
выполнении обещания, по-прежнему должны вызываться в соответствии со спецификацией асинхронно. Это необходимо для обеспечения согласованного поведения при использовании обещаний для сочетания синхронных и асинхронных действий.Поэтому, когда вы вызываете
resolve
обратный вызов, он ставится в очередь , и выполнение функции немедленно продолжается с любым кодом, следующим заresolve()
вызовом.Только после того, как цикл событий JS будет возвращен в управление, обратный вызов может быть удален из очереди и фактически вызван.
источник
EnqueueJob
, который вызывается.then
.