诺兰';s承诺/A+;JavaScript难题
我已经阅读了Nolan Lawson的几篇文章,但仍然对JavaScript中的承诺有一些疑问。在诺兰的帖子末尾,你可以找到四个谜题的答案(我在这里附上了截图) 因此,我有几个问题:诺兰';s承诺/A+;JavaScript难题,javascript,promise,es6-promise,Javascript,Promise,Es6 Promise,我已经阅读了Nolan Lawson的几篇文章,但仍然对JavaScript中的承诺有一些疑问。在诺兰的帖子末尾,你可以找到四个谜题的答案(我在这里附上了截图) 因此,我有几个问题: 为什么第一个谜题中的doSomethingElse()函数有未定义的值?在我看来,它一定有resultOfDoSomething类似于第四个拼图 第三个和第四个拼图有什么区别?在第一个的第三个拼图中,然后我们写doSomethingElse(),在第四个拼图中,我们只写函数名,doSomethingElse。怎么可
doSomethingElse()
函数有未定义的值?在我看来,它一定有resultOfDoSomething
类似于第四个拼图
的第三个拼图中,然后我们写doSomethingElse()
,在第四个拼图中,我们只写函数名,doSomethingElse
。怎么可能呢?在第四个谜题的和中,doSomethingElse真正做了什么
doSomethingElse()
函数与doSomething
同时启动doSomething
的预期结果被传递给匿名函数(该函数甚至不接受参数)。因此,无论通过什么,都会丢失。调用doSomethingElse
时不带任何参数,因此第一个函数参数是undefined
第三个和第四个拼图有什么区别?在第三个拼图中,我们先写doSomethingElse(),在第四个拼图中,我们在这里只写函数名-doSomethingElse。怎么可能呢?在第四个谜题中,doSomethingElse到底做了什么
JavaScript中的函数是可以随意传递的对象。这实际上就是整个回调传递的工作原理:有一个函数(这里是然后)将函数作为参数,然后调用该参数
因此,在后一个代码中,传递给然后
的函数是doSomethingElse
,这就是后来调用的函数。但在前者中,我们直接调用doSomethingElse
(带括号()
)。因此传递给的是该函数的返回值,该函数不太可能是一个一旦承诺完成就可以计算的函数
为什么第三个拼图中的doSomethingElse()函数与doSomething函数同时启动
正如我所说,在调用doSomething
的同时,会立即调用该函数。只有返回值被传递到然后
,一旦承诺解决,就会调用该值
为什么doSomethingElse()
在第一个谜题[获得通过]未定义中起作用
让我们看一个更简单的例子:
foo(); // Line #1
foo(42); // Line #2
这两条线的区别是什么?在第1行,我们调用foo,但不传递任何值(因此未定义),而在第2行,我们调用foo,并传递它42
回到岗位:
doSomething().then(function () {
return doSomethingElse( );
// ^-- we are not passing a value
}).then(finalHandler);
这和第四个拼图有什么不同?在第四个谜题中,我们将函数的引用传递给,然后传递给。向承诺提供对函数的引用,允许它稍后使用承诺的结果调用它
第三个和第四个拼图有什么区别?在第三个拼图中[…]我们写doSomethingElse()
,在第四个拼图中我们写[…]doSomethingElse
为了解释第三个和第四个谜题的区别,让我们看一些简单的例子。以下两行有何区别:
var foo = function foo() {
return 42;
};
var a = foo; // line #1
var b = foo(); // line #2
在上面的代码段中,a
将包含对函数foo
的引用,而b
将包含调用foo的结果(即42)
为什么第三个拼图中的doSomethingElse()
与doSomething
同时开始
与第3个和第4个函数之间的区别类似,请注意使用()
调用该函数。这里我们调用了doSomething()
和doSomethingElse()
,而不是等待承诺“解决”(等待第一次调用完成)。在此之前,让我们逐步完成执行:
执行返回承诺的doSomething
将doSomethingElse()
附加到承诺,但请稍候,doSomethingElse()
正在调用doSomethingElse()
,因此这将异步发生,我们将把它返回的承诺附加到返回的承诺doSomething()
将函数finalHandler
附加到承诺中
您必须注意:doSomethingElse
是一个函数引用,而doSomethingElse()
表示您立即“调用”该函数。在这里你可以得到函数的结果,如果有的话
关于承诺,我理解:
A) “then”方法获取上一次调用的结果,并将其作为参数传递给自己的参数(如果它是函数)
B) 只有当“then”方法中的函数返回某些内容时,执行才会延迟
在这些情况下,我们有:
谜题1)ResultToDoSomething用作匿名函数的参数
function (){ return doSomethingElse ();}
这将调用不带参数的doSomethingElse()
谜题2)匿名函数不返回数据,因此立即执行下一个“then”
谜题3)表达式doSomethingElse()
是doSomethingElse调用的结果。这个值被用作“then”方法的参数,因为它不是一个函数(在本例中!),所以我们可以传递给另一个“then”
finalHandler接收最后的有效结果作为参数,在本例中为ResultToDoSomething
谜题4)每个“then”方法都接收到参数
var foo = function foo() {
return 42;
};
var a = foo; // line #1
var b = foo(); // line #2
function (){ return doSomethingElse ();}
doSomething().then(function(resultOfDoSomething) {
// it's here: ^^^^^^^^^^^^^^^^^^^
return doSomethingElse( );
// but not there: ^^ - Ooops!
});
promise.then(function callback(res) {
…
});
function callback(res) {
…
}
promise.then(callback);
var promise = doSomething();
doSomethingElse();
promise.then(finalHandler);