我正在研究JavaScript中的Promises。我很感兴趣,我可以结合ECMAScript承诺与其他实现,例如jQuery $.Deferred
。我很惊讶,当Promises.all
工作良好与jQuery $.Deferred
。我试图在jQuery源代码和CommonJS承诺/A规格中找到答案,但我仍然误解了为什么这段代码像我预期的那样工作(做console.log
后10秒,而不是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
的某个字段或方法来理解它是否被解析。这个方法/字段是什么?
promises A+规范(承诺展开规范基于原生承诺的使用)就是专门为此构建的。
为了使库能够很好地相互通信,规范是围绕一个方法构建的:.then
.
then方法指定了承诺的延续是如何工作的。jQuery承诺从1.8版本开始公开.then
,这意味着他们会尝试参与这个游戏。虽然jQuery的deferred和promises是而不是 promises/A+ promises——它们试图成为promises/A promise,这意味着:
return Promise.resolve($.get(...))
总是有效的。A+承诺(和本机承诺)将递归地吸收每个.then
表,并在返回它时使用它的值进行解析。
Promise.resolve({then:function(fn){ return fn(3); }}).then(function(el){
console.log(el); // this logs 3
})
如果我们检查规格,可以看到:
让result为Invoke(nextPromise,
"then"
, (resolveElement, promiseCapability.[[Reject]])).
(也与此相关)
调用.then
并在.then
表解析
jQuery的deferred使用了一个非标准的promise实现,所以它不能使用原生promise(也就是说,你不能预测地$.when
一个原生promise)。反过来也行。