Обещания Нолана / головоломки JavaScript a+
я прочитала у нас проблема с обещаниями Нолан Лоусон несколько раз, но все еще есть некоторые вопросы об обещаниях в JavaScript. В конце поста Нолана вы можете найти ответы на четыре головоломки (я приложил скриншоты здесь).
так, у меня есть несколько вопросов:
почему
doSomethingElse()
функция в 1-й головоломки естьundefined
значение? По-моему, должно быть ... --2--> как в 4-м головоломка.в чем разница между 3-й и 4-й головоломки? В 3-й головоломки в первой
then
пишемdoSomethingElse()
и в 4-й головоломке мы пишем здесь только название функции,doSomethingElse
. Как это возможно? Что действительноdoSomethingElse
сделать внутриthen
4-й пазл?почему
doSomethingElse()
функция в 3-й головоломки начать в тот же момент, какdoSomething
?
6 ответов
- почему
doSomethingElse()
функция в 1-й головоломки [пройти]undefined
?
давайте рассмотрим более простой пример:
foo(); // Line #1
foo(42); // Line #2
разница между двумя линиями в чем? В строке #1 мы вызываем foo, но не передаем его значение (следовательно undefined
) в то время как на линии № 2 мы вызываем foo и передаем его 42.
возвращаясь к сообщению:
doSomething().then(function () {
return doSomethingElse( );
// ^-- we are not passing a value
}).then(finalHandler);
чем это отличается от 4-й пазл? В 4-я головоломка мы передаем ссылку на функцию в then
. Предоставление обещания ссылка на функцию позволяет ей вызывать его в более позднее время с результатом обещания.[1]
- в чем разница между 3-й и 4-й головоломки? В 3-й головоломке [...] мы пишем
doSomethingElse()
и в 4-й головоломке мы пишем [...]doSomethingElse
.
чтобы объяснить различия в 3-й и 4-я головоломка, давайте посмотрим на более простые примеры. Чем отличаются следующие две строки:
var foo = function foo() {
return 42;
};
var a = foo; // line #1
var b = foo(); // line #2
в фрагменте выше, a
будет содержать ссылку на функцию foo
, тогда как b
будет содержать результат вызова foo (который будет 42).
- почему
doSomethingElse()
в 3-й головоломки начать в тот же момент, какdoSomething
?
похожие на различия между 3-м и 4-м функции, обратите внимание на использование ()
to invoke (или вызовов) функция. Здесь мы называем оба doSomething()
и doSomethingElse()
вместо того, чтобы ждать обещания "разрешить" (ожидание завершения первого вызова). прежде чем приступим к исполнению:
- выполнить
doSomething
который возвращает обещание - прикрепите
doSomethingElse()
к обещанию-но подождите,doSomethingElse()
- это нас зоветdoSomethingElse()
, Так что это произойдет асинхронно, и мы приложим обещание возвращение к обещаниюdoSomething()
вернулся. - прикрепить функцию
finalHandler
обещание
doSomething().then(function () { return doSomethingElse(); });
почему функция doSomethingElse () в 1-й головоломке имеет неопределенное значение? На мой взгляд, это должно привести к чему-то вроде 4-й головоломки.
обещанный результат doSomething
передается анонимной функции (которая даже не принимает аргумент). Поэтому все, что там проходит, теряется. И doSomethingElse
вызывается без каких-либо аргументов, поэтому первый аргумент функции undefined
.
doSomething().then(doSomethingElse()); doSomething().then(doSomethingElse);
что разница между 3-й и 4-й уровень? В 3-й головоломке сначала пишем doSomethingElse (), а в 4-й головоломке пишем здесь только название функции - doSomethingElse. Как это возможно? Что на самом деле делает doSomethingElse в то 4-й головоломки?
функции в JavaScript-это объекты, которые вы можете передавать по своему усмотрению. Вот как на самом деле работает вся передача обратного вызова: есть функция (здесь это then
), которая принимает функцию в качестве параметра, который затем позже вызывается.
таким образом, в последнем коде функция, которая передается в then
is doSomethingElse
Так что это функция, которая составляет позже называется. Но в первом случае мы называем doSomethingElse
напрямую (в скобках ()
). Так что передается then
- это возвращаемое значение этой функции, которая вряд ли является функцией, которая может быть оценена после завершения обещания.
почему функция doSomethingElse () в 3-й головоломки начать в тот же момент, как doSomething?
как я уже сказал, функция немедленно вызывается, в то же время вы вызываете doSomething
. Только возвращаемое значение передается в then
который затем будет называться, как только обещание разрешится.
вы должны обратить внимание: doSomethingElse
является ссылкой на функцию while doSomethingElse()
означает, что вы сразу" вызываете " функцию. Здесь вы можете получить результат функции, если таковые имеются...
насчет обещаний я понял, что:
A) метод "then" принимает результат предыдущего вызова и передает его как параметр своему собственному параметру, если это функция.
B) выполнение задерживается только в том случае, если функция внутри метода " then что-то.
в этих ситуациях мы имеем:
головоломка 1) resultOfDoSomething используется в качестве параметра для анонимной функции
function (){ return doSomethingElse ();}
Это doSomethingElse()
без параметров.
головоломка 2) анонимная функция не возвращает данные, поэтому следующий "затем" немедленно выполняется
Головоломка 3) выражение doSomethingElse()
является результатом вызова doSomethingElse. Это значение используется в качестве параметра для метода then, и поскольку он не является функцией (в данном примере!), мы можем перейти к другому "тогда"...
finalHandler получает последние допустимые результаты в качестве параметров, в этом случае resultOfDoSomething.
головоломка 4) Каждый метод "тогда" получает в качестве параметра ссылку на функцию. Каждая из этих функций будет вызываться с предыдущими результатами в качестве параметров. Таким образом, каждая функция должна ждать результата предыдущего выполнения... и вот у вас очередь из обещаний...
Long story short-простые 2 правила, чтобы сделать ваши примеры понятными:
возврат значения изнутри
.then
Это то же самое, что вернуть обещание, которое разрешается с этим значением.когда вы ничего не возвращаете, это то же самое, что и возвращение
undefined
, который в свою очередь вводит правило #1.
Если вы держите эти 2 в виду, ваши обещания головоломки становятся ясными, как день.
почему
doSomethingElse()
функция в 1-й головоломки естьundefined
значение? По-моему, должно быть ... --6--> как в 4-й головоломки.
Неа. The resultOfDoSomething
передается обратному вызову, что then
был вызван, да, но мы просто игнорируем его в первом коде:
doSomething().then(function(resultOfDoSomething) {
// it's here: ^^^^^^^^^^^^^^^^^^^
return doSomethingElse( );
// but not there: ^^ - Ooops!
});
в чем разница между 3-й и 4-й головоломки? В 3-й головоломке в первой тогда напишем
doSomethingElse()
и в 4-й головоломке мы пишем здесь только имя функции,doSomethingElse
. Как это возможно? Что действительноdoSomethingElse
сделать внутри то 4-й головоломки?
как вы, вероятно, знаете, это разница между вызываемой функцией и самой функцией.
кроме того, мы всегда хотим - no: must - передать функцию обратного вызова в then(…)
. Следующие два эквивалентны:
promise.then(function callback(res) {
…
});
function callback(res) {
…
}
promise.then(callback);
это ожидается-вы передаете функцию вызову, поэтому она прикована к обещанию как обычный. Но!--13--> (с вызовом) больше не является функцией:
почему
doSomethingElse()
функция в 3-й головоломки начать в тот же момент, какdoSomething
?
потому что он вызывается сразу в выражении then(doSomethingElse())
- это на самом деле называется до then
, к которому это аргумент. Так это на самом деле называется через мгновение после doSomething()
, но на том же повороте цикла событий; и два асинхронных somethings будут работать в параллельный.
и then
принимает только аргументы функции, все остальное -игнорировать. Таким образом, здесь нет цепей, это то же самое, что делать
var promise = doSomething();
doSomethingElse();
promise.then(finalHandler);
не то, что мы хотим!
кстати, они также объясняются как"Расширенная Ошибка #3: обещания против обещаний фабрики" и "Расширенная Ошибка #5: обещания проваливаются", которые я бы оба рассматривал как ошибки новичка : -)
Я думаю, что порядок выполнения всегда сначала doSomethingElse затем doSomethingElse и finalHandler. Это просто синтаксис JavaScript.
разница в том, что args передают функции разные.
две функции возвращают два обещания.Порядок выполнения двух обещаний показан на рисунках, которые вы разместили. Я думаю, что автор имеет в виду порядок двух обещаний, а не порядок выполнения функции.
/**
* Created by tshungle on 17-2-24.
*/
'use strict'
function doSomething() {
console.log("doSomething start");
sleep(1000)
console.log("doSomething end");
return new Promise(function (resolve, reject) {
setTimeout(function() {
console.log("Promise of doSomething is about to resolve");
resolve("doSomething resolvation")
}, 2500);
});
}
function doSomethingElse() {
console.log("doSomethingElse start");
sleep(1000);
console.log("doSomethingElse end");
return new Promise(function (resolve, reject) {
setTimeout(function() {
console.log("Promise of doSomethingElse is about to resolve");
resolve("doSomethingElse resolvation")
}, 2500);
});
}
function finalHandler(result) {
console.log("finalHandler result is:", result);
}
function sleep(ms) {
var stop = new Date().getTime();
while(new Date().getTime() < stop + ms) {
;
}
}
//1
doSomething().then(function () {
return doSomethingElse();
}).then(finalHandler);
//2
// doSomething().then(function () {
// doSomethingElse();
// }).then(finalHandler);
//
//3
// doSomething().then(doSomethingElse())
// .then(finalHandler);
//4
// doSomething().then(doSomethingElse)
// .then(finalHandler);