Javascript 为什么Promise构造函数需要调用';解决';完成时,但';然后';不会-它会返回一个值吗?
当我开始研究Javascript 为什么Promise构造函数需要调用';解决';完成时,但';然后';不会-它会返回一个值吗?,javascript,promise,ecmascript-6,es6-promise,Javascript,Promise,Ecmascript 6,Es6 Promise,当我开始研究Promises时,我对以下问题的理解停止了,我发现这个问题没有得到讨论(我发现的只是对Promise构造函数和Promise“然后”函数的具体讨论,而不是对它们的设计模式进行比较的讨论) 1。承诺构造函数 ,我们使用了Promise构造函数(添加了我的评论): 链接 因为then方法返回一个承诺,所以您可以很容易地进行链接 电话 var p2=新承诺(函数(解析、拒绝){ resolve(1);//在Promise构造函数和then方法之间没有对应关系,因为它们是两个独立的东西,
Promise
s时,我对以下问题的理解停止了,我发现这个问题没有得到讨论(我发现的只是对Promise
构造函数和Promise
“然后”函数的具体讨论,而不是对它们的设计模式进行比较的讨论)
1。承诺
构造函数
,我们使用了Promise构造函数(添加了我的评论):
链接
因为then
方法返回一个承诺,所以您可以很容易地进行链接
电话
var p2=新承诺(函数(解析、拒绝){
resolve(1);//在Promise
构造函数和then
方法之间没有对应关系,因为它们是两个独立的东西,设计用于不同的目的
Promise
构造函数仅用于1个异步函数。事实上,正如您所说,它是基于调用resolve
/reject
回调来异步发送值而构建的,在这种情况下没有返回值
Promise
构造函数本身确实接受了这个“解析器”回调(它同步地传递给resolve
和reject
)实际上是旧的延迟模式的增强,并且与然后的回调没有预期的相似性
var p = new Promise(function(res, rej) { | var def = Promise.Deferred();
setTimeout(res, 100); | setTimeout(def.resolve, 100);
}); | var p = def.promise;
相比之下,then
回调是典型的异步回调,您可以从它们返回
。它们被异步调用以接收值
总结这些差异:
Promise
是构造函数,而then
是方法
Promise
接受一次回调,而then
最多需要两次回调
Promise
同步调用其回调,而then
异步调用其回调
Promise
始终调用其回调,
则
可能不会调用其回调(如果承诺未履行/拒绝)
Promise
将解析/拒绝承诺的功能传递给回调,
然后
传递调用它的承诺的结果值/拒绝原因
Promise
调用其回调以执行副作用(调用reject
/resolve
),
然后
调用其对结果值的回调(用于链接)
是的,这两个函数都返回承诺,尽管它们与许多其他函数都具有相同的特性(Promise.resolve
,Promise.reject
,fetch
,…)事实上,所有这些都基于同样的承诺构造和解析/拒绝功能,promise
构造函数也提供了这些功能,尽管这不是它们的主要目的。然后
基本上提供了将oncompleted
/onRejected
回调附加到现有承诺的能力,这是rather与Promise
构造函数的直径
两者都使用回调只是巧合——不是历史上的侥幸,而是语言特性的共同适应
1:理想情况下,您永远不会需要它,因为所有本机异步API都会返回承诺承诺构造函数执行器函数的全部要点是将解析和拒绝函数分发给使用非承诺的代码,将其包装并转换为使用承诺。如果您想将其仅限于同步函数,则可以,可以使用函数的返回值来代替,但这是愚蠢的,因为有用的部分是将解析器和拒绝函数分发给稍后实际运行的代码(在返回之后),例如传递给某个异步API的回调。非常好,对我非常有帮助。这个答案是对他的补充。为了可视化Promise()
构造函数和then()之间的关系
method,我创建了这个图表。我希望它能帮助某些人……甚至是我,几个月后
这里的主要思想是传递给Promise()
构造函数的“executor”函数设置运行中的任务,这些任务将设置Promise的状态;而传递给then()
的处理程序将对Promise的状态做出反应
(代码示例改编自。)
这是一个高度简化的工作原理视图,省略了许多重要的细节。但我认为,如果一个人能够很好地把握预期目的,那么当他进入细节时,这将有助于避免混淆
一些精选的细节
遗嘱执行人立即被传唤
一个重要的细节是传递给Promise()
构造函数的执行器函数立即调用(在构造函数返回Promise之前);而传递给then()
方法的处理函数直到之后才会调用(如果有)
Bergi提到了这一点,但我想重申这一点,但不使用术语a/synchronously,如果您没有仔细阅读,这可能会混淆:异步调用某个函数与异步调用函数之间的区别在通信中很容易被掩盖
resolve()
不是onFulfill()
我想强调的另一个细节是,传递给Promise()
构造函数的executor函数的resolve()
和reject()
回调不是以后传递给then()
方法的回调
p.then(onFulfilled, onRejected);
var p2 = new Promise(function(resolve, reject) {
resolve(1); // <-- Stage 1 again
});
p2.then(function(value) {
console.log(value); // 1
return value + 1; // <-- Call this Stage 2
}).then(function(value) {
console.log(value); // 2
});
var p = new Promise(function(res, rej) { | var def = Promise.Deferred();
setTimeout(res, 100); | setTimeout(def.resolve, 100);
}); | var p = def.promise;
p.then(function(val) { … });