我正在研究JavaScript中的Promises。我很有兴趣将ECMAScript Promises与其他实现结合起来,例如jQuery $.Deferred
。当Promises.all
与jQuery $.Deferred
一起正常工作时,我感到很惊讶。我试图在jQuery源代码和CommonJS Promises / A规范中找到答案,但我仍然误解了为什么这段代码按照我的预期工作(10秒后做console.log
,而不是5秒):
var promise = new Promise(function (resolve, reject) {
setTimeout(function () {
resolve();//resolve first promise after 5 secs
console.log('Promise resolved');
}, 5000);
});
var deferred = $.Deferred();
setTimeout(function () {
deferred.resolve();//resolve after 10 seconds
console.log('Deferred resolved');
}, 10000);
Promise.all([promise,deferred]).then(function () {
console.log('All is done');//log after 10 seconds
});
你有什么想法吗?
Promise.all
必须依赖$.Deferred
的某些字段或方法来理解是否已解决。那个方法/领域是什么?
答案 0 :(得分:8)
承诺A +规范(承诺展开规范基于本机承诺使用的规范)是专门为此而构建的。
由于图书馆的设计目标很好,规范是围绕一个方法构建的:.then
。
then方法指定了promise的延续如何工作。从版本1.8开始,jQuery承诺公开.then
,这意味着他们试图参与这个游戏。虽然jQuery延迟和承诺是不承诺/ A +承诺 - 他们试图成为Promises / A承诺,意味着以下内容:
return Promise.resolve($.get(...))
永远有效。 A + promises(和原生承诺)将递归地同化每个.then
,并在返回时以其值解析。
Promise.resolve({then:function(fn){ return fn(3); }}).then(function(el){
console.log(el); // this logs 3
})
如果我们检查specification,我们可以看到:
让结果成为Invoke( nextPromise ,
"then"
,( resolveElement , promiseCapability 。[ [拒绝]]))。
(也相关的是this)
当.then
能够解析
.then
并解析下一个项目
jQuery延迟使用非标准的承诺实现,因此它不能消耗原生承诺(也就是说,你可以预测$.when
本地承诺。反过来工作。