诺兰的 Promises/A+ JavaScript 个谜题
Nolan's Promises/A+ JavaScript puzzles
我读过 Nolan Lawson 的 We have a problem with promises 几遍,但对 JavaScript 中的承诺仍有一些疑问。在 Nolan 的 post 结尾处,您可以找到四个谜题的答案(我在此处附上了屏幕截图)。
所以,我有几个问题:
为什么第一个谜题中的doSomethingElse()
函数有undefined
值?在我看来,它必须有 resultOfDoSomething
就像第 4 个谜题中那样。
第三个和第四个谜题有什么区别?在第一个 then
的第 3 个谜题中,我们写 doSomethingElse()
,在第 4 个谜题中,我们只在这里写函数名称 doSomethingElse
。这怎么可能? doSomethingElse
在第 4 个谜题的 then
中到底做了什么?
为什么第三个谜题中的doSomethingElse()
函数和doSomething
同时开始?
doSomething().then(function () {
return doSomethingElse();
});
Why does doSomethingElse() function in 1-st puzzle have undefined value? To my mind, it must have resultOfDoSomething like in 4-th puzzle.
doSomething
的承诺结果被传递给匿名函数(它甚至不接受参数)。因此,无论通过什么,都会丢失。并且 doSomethingElse
被调用时没有任何参数,所以第一个函数参数是 undefined
.
doSomething().then(doSomethingElse());
doSomething().then(doSomethingElse);
What's the difference beetwen 3-rd and 4-th puzzles? In 3-rd puzzle in first then we write doSomethingElse() and in 4-th puzzle we write here only the name of function - doSomethingElse. How is it possible? What does really doSomethingElse do in then of 4-th puzzle?
JavaScript 中的函数是您可以随意传递的对象。这实际上就是整个回调传递的工作原理:有一个函数(这里是 then
),它接受一个函数作为参数,然后调用它。
所以在后面的代码中,传递给 then
的函数是 doSomethingElse
所以这就是 之后 调用的函数。但在前者中,我们直接调用doSomethingElse
(带括号()
)。因此,传递给 then
的是该函数的 return 值——这不太可能是一旦承诺完成就可以评估的函数。
Why does doSomethingElse() function in 3-rd puzzle start at the same moment as doSomething?
正如我所说,函数被立即调用,同时你调用doSomething
。只有 return 值被传递给 then
,一旦 promise 解决,它就会被调用。
- Why does
doSomethingElse()
function in 1st puzzle [get passed] undefined
?
让我们看一个更简单的例子:
foo(); // Line #1
foo(42); // Line #2
两条线的区别是什么?在第 1 行,我们调用 foo 但没有传递任何值(因此 undefined
),而在第 2 行我们调用 foo 并传递给它 42.
回到post:
doSomething().then(function () {
return doSomethingElse( );
// ^-- we are not passing a value
}).then(finalHandler);
这与第 4 个谜题有何不同?在第 4 个谜题中,我们将函数的引用传递给 then
。为 promise 提供对该函数的引用,允许它在稍后使用 promise 的结果调用它。[1]
- What's the difference between the 3rd and 4th puzzles? In the 3rd puzzle [...] we write
doSomethingElse()
and in the 4th puzzle we write [...] doSomethingElse
.
为了说明第3题和第4题的区别,让我们看一些更简单的例子。以下两行有何不同:
var foo = function foo() {
return 42;
};
var a = foo; // line #1
var b = foo(); // line #2
在上面的代码片段中,a
将包含对函数 foo
的引用,而 b
将包含调用 foo 的结果(即 42)。
- Why does
doSomethingElse()
in the 3rd puzzle start at the same moment as doSomething
?
类似第3个和第4个函数的区别,注意使用()
来调用(或调用)函数。这里我们同时调用 doSomething()
和 doSomethingElse()
而不是等待对 "resolve" 的承诺(等待第一个调用完成)。在让我们逐步执行之前:
- 执行
doSomething
其中 returns 一个 Promise
- 将
doSomethingElse()
附加到 promise——但是等等,doSomethingElse()
是我们调用 doSomethingElse()
,所以这将发生异步,我们将附加 promise 它 returns兑现 doSomething()
的承诺。
- 将函数
finalHandler
附加到 promise
你必须注意:doSomethingElse
是一个函数引用,而doSomethingElse()
意味着你马上"call"这个函数。在这里你可以得到函数的结果,如果有的话...
关于承诺,我的理解是:
A) "then" 方法获取上一次调用的结果,如果它是一个函数,则将其作为参数传递给它自己的参数。
B) 仅当 "then" 方法中的函数 return 有问题时才会延迟执行。
在这些情况下,我们有:
谜题1) resultOfDoSomething被用作匿名函数的参数
function (){ return doSomethingElse ();}
这会在没有参数的情况下调用 doSomethingElse()
。
谜题2)匿名函数没有return数据所以下一个"then"立即执行
谜题3)表达式doSomethingElse()
是调用doSomethingElse的结果。这个值用作 "then" 方法的参数,因为它不是一个函数(在这个例子中!),我们可以传递给另一个 "then"...
finalHandler 接收最后一个有效结果作为参数,在本例中为 resultOfDoSomething。
谜题 4) 每个 "then" 方法都接收一个函数的引用作为参数。这些函数中的每一个都将以先前的结果作为参数调用。所以,每个函数都必须等待上一次执行的结果……这里有承诺队列……
长话短说 - 简单的 2 条规则使您的示例易于理解:
从 .then
内部返回一个值与 return 使用该值解析的承诺相同。
当你 return 什么都没有时,它与 returning undefined
相同,这反过来又制定了规则 #1。
如果您牢记这 2 点,您的承诺难题就会变得一目了然。
Why does doSomethingElse()
function in the 1st puzzle have undefined
value? To my mind, it must have resultOfDoSomething
like in the 4th puzzle.
没有。 resultOfDoSomething
被传递给调用 then
的回调,是的,但我们只是在第一个代码中忽略它:
doSomething().then(function(resultOfDoSomething) {
// it's here: ^^^^^^^^^^^^^^^^^^^
return doSomethingElse( );
// but not there: ^^ - Ooops!
});
What's the difference between the 3rd and 4th puzzles? In the 3rd puzzle in the first then we write doSomethingElse()
and in the 4th puzzle we write here only the name of function, doSomethingElse
. How is it possible? What does really doSomethingElse
do inside the then of the 4th puzzle?
你可能知道,这是被调用函数和函数本身的区别。
此外,我们总是希望 - 不:必须 - 将回调函数传递给 then(…)
。下面两个是等价的:
promise.then(function callback(res) {
…
});
function callback(res) {
…
}
promise.then(callback);
这是预期的 - 您将一个函数传递给调用,因此它像往常一样链接到承诺上。但是 callback()
(通过调用)不再是一个函数:
Why does doSomethingElse()
function in 3rd puzzle start at the same moment as doSomething
?
因为它在表达式 then(doSomethingElse())
中被立即调用 - 它实际上是在 then
之前被调用的,它是一个参数。所以它实际上是在 doSomething()
之后调用的,但是在同一个事件循环中;并且两个异步的东西将 运行 并行。
此外,then
只接受函数参数,其他所有内容 都会被忽略 。所以这里没有链接,它和做的一样
var promise = doSomething();
doSomethingElse();
promise.then(finalHandler);
不是我们想要的!
顺便说一句,这些也被解释为“高级错误#3:承诺与承诺工厂”和“高级错误#5:承诺落空",我都认为这是菜鸟错误:-)
我觉得执行顺序总是先doSomethingElse再doSomethingElse和finalHandler。这只是 JavaScript 语法。
区别在于传递给函数的参数不同。
两个函数return两个promises.The两个promise的执行顺序显示在你发布的图中。我认为作者的意思是两个承诺的顺序而不是函数执行顺序。
/**
* 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);
我读过 Nolan Lawson 的 We have a problem with promises 几遍,但对 JavaScript 中的承诺仍有一些疑问。在 Nolan 的 post 结尾处,您可以找到四个谜题的答案(我在此处附上了屏幕截图)。
所以,我有几个问题:
为什么第一个谜题中的
doSomethingElse()
函数有undefined
值?在我看来,它必须有resultOfDoSomething
就像第 4 个谜题中那样。第三个和第四个谜题有什么区别?在第一个
then
的第 3 个谜题中,我们写doSomethingElse()
,在第 4 个谜题中,我们只在这里写函数名称doSomethingElse
。这怎么可能?doSomethingElse
在第 4 个谜题的then
中到底做了什么?为什么第三个谜题中的
doSomethingElse()
函数和doSomething
同时开始?
doSomething().then(function () { return doSomethingElse(); });
Why does doSomethingElse() function in 1-st puzzle have undefined value? To my mind, it must have resultOfDoSomething like in 4-th puzzle.
doSomething
的承诺结果被传递给匿名函数(它甚至不接受参数)。因此,无论通过什么,都会丢失。并且 doSomethingElse
被调用时没有任何参数,所以第一个函数参数是 undefined
.
doSomething().then(doSomethingElse()); doSomething().then(doSomethingElse);
What's the difference beetwen 3-rd and 4-th puzzles? In 3-rd puzzle in first then we write doSomethingElse() and in 4-th puzzle we write here only the name of function - doSomethingElse. How is it possible? What does really doSomethingElse do in then of 4-th puzzle?
JavaScript 中的函数是您可以随意传递的对象。这实际上就是整个回调传递的工作原理:有一个函数(这里是 then
),它接受一个函数作为参数,然后调用它。
所以在后面的代码中,传递给 then
的函数是 doSomethingElse
所以这就是 之后 调用的函数。但在前者中,我们直接调用doSomethingElse
(带括号()
)。因此,传递给 then
的是该函数的 return 值——这不太可能是一旦承诺完成就可以评估的函数。
Why does doSomethingElse() function in 3-rd puzzle start at the same moment as doSomething?
正如我所说,函数被立即调用,同时你调用doSomething
。只有 return 值被传递给 then
,一旦 promise 解决,它就会被调用。
- Why does
doSomethingElse()
function in 1st puzzle [get passed]undefined
?
让我们看一个更简单的例子:
foo(); // Line #1
foo(42); // Line #2
两条线的区别是什么?在第 1 行,我们调用 foo 但没有传递任何值(因此 undefined
),而在第 2 行我们调用 foo 并传递给它 42.
回到post:
doSomething().then(function () {
return doSomethingElse( );
// ^-- we are not passing a value
}).then(finalHandler);
这与第 4 个谜题有何不同?在第 4 个谜题中,我们将函数的引用传递给 then
。为 promise 提供对该函数的引用,允许它在稍后使用 promise 的结果调用它。[1]
- What's the difference between the 3rd and 4th puzzles? In the 3rd puzzle [...] we write
doSomethingElse()
and in the 4th puzzle we write [...]doSomethingElse
.
为了说明第3题和第4题的区别,让我们看一些更简单的例子。以下两行有何不同:
var foo = function foo() {
return 42;
};
var a = foo; // line #1
var b = foo(); // line #2
在上面的代码片段中,a
将包含对函数 foo
的引用,而 b
将包含调用 foo 的结果(即 42)。
- Why does
doSomethingElse()
in the 3rd puzzle start at the same moment asdoSomething
?
类似第3个和第4个函数的区别,注意使用()
来调用(或调用)函数。这里我们同时调用 doSomething()
和 doSomethingElse()
而不是等待对 "resolve" 的承诺(等待第一个调用完成)。在让我们逐步执行之前:
- 执行
doSomething
其中 returns 一个 Promise - 将
doSomethingElse()
附加到 promise——但是等等,doSomethingElse()
是我们调用doSomethingElse()
,所以这将发生异步,我们将附加 promise 它 returns兑现doSomething()
的承诺。 - 将函数
finalHandler
附加到 promise
你必须注意:doSomethingElse
是一个函数引用,而doSomethingElse()
意味着你马上"call"这个函数。在这里你可以得到函数的结果,如果有的话...
关于承诺,我的理解是:
A) "then" 方法获取上一次调用的结果,如果它是一个函数,则将其作为参数传递给它自己的参数。
B) 仅当 "then" 方法中的函数 return 有问题时才会延迟执行。
在这些情况下,我们有:
谜题1) resultOfDoSomething被用作匿名函数的参数
function (){ return doSomethingElse ();}
这会在没有参数的情况下调用 doSomethingElse()
。
谜题2)匿名函数没有return数据所以下一个"then"立即执行
谜题3)表达式doSomethingElse()
是调用doSomethingElse的结果。这个值用作 "then" 方法的参数,因为它不是一个函数(在这个例子中!),我们可以传递给另一个 "then"...
finalHandler 接收最后一个有效结果作为参数,在本例中为 resultOfDoSomething。
谜题 4) 每个 "then" 方法都接收一个函数的引用作为参数。这些函数中的每一个都将以先前的结果作为参数调用。所以,每个函数都必须等待上一次执行的结果……这里有承诺队列……
长话短说 - 简单的 2 条规则使您的示例易于理解:
从
.then
内部返回一个值与 return 使用该值解析的承诺相同。当你 return 什么都没有时,它与 returning
undefined
相同,这反过来又制定了规则 #1。
如果您牢记这 2 点,您的承诺难题就会变得一目了然。
Why does
doSomethingElse()
function in the 1st puzzle haveundefined
value? To my mind, it must haveresultOfDoSomething
like in the 4th puzzle.
没有。 resultOfDoSomething
被传递给调用 then
的回调,是的,但我们只是在第一个代码中忽略它:
doSomething().then(function(resultOfDoSomething) {
// it's here: ^^^^^^^^^^^^^^^^^^^
return doSomethingElse( );
// but not there: ^^ - Ooops!
});
What's the difference between the 3rd and 4th puzzles? In the 3rd puzzle in the first then we write
doSomethingElse()
and in the 4th puzzle we write here only the name of function,doSomethingElse
. How is it possible? What does reallydoSomethingElse
do inside the then of the 4th puzzle?
你可能知道,这是被调用函数和函数本身的区别。
此外,我们总是希望 - 不:必须 - 将回调函数传递给 then(…)
。下面两个是等价的:
promise.then(function callback(res) {
…
});
function callback(res) {
…
}
promise.then(callback);
这是预期的 - 您将一个函数传递给调用,因此它像往常一样链接到承诺上。但是 callback()
(通过调用)不再是一个函数:
Why does
doSomethingElse()
function in 3rd puzzle start at the same moment asdoSomething
?
因为它在表达式 then(doSomethingElse())
中被立即调用 - 它实际上是在 then
之前被调用的,它是一个参数。所以它实际上是在 doSomething()
之后调用的,但是在同一个事件循环中;并且两个异步的东西将 运行 并行。
此外,then
只接受函数参数,其他所有内容 都会被忽略 。所以这里没有链接,它和做的一样
var promise = doSomething();
doSomethingElse();
promise.then(finalHandler);
不是我们想要的!
顺便说一句,这些也被解释为“高级错误#3:承诺与承诺工厂”和“高级错误#5:承诺落空",我都认为这是菜鸟错误:-)
我觉得执行顺序总是先doSomethingElse再doSomethingElse和finalHandler。这只是 JavaScript 语法。
区别在于传递给函数的参数不同。
两个函数return两个promises.The两个promise的执行顺序显示在你发布的图中。我认为作者的意思是两个承诺的顺序而不是函数执行顺序。
/**
* 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);