给同一个延迟承诺(deferred promise)链接多个done()回调函数

11
简言之,我希望有一个通用回调函数,在成功的ajax调用情况下始终被触发,然后根据调用方法的位置提供单独的回调功能。
这似乎是有效的。我的问题是这是否是promise对象的正确使用方式,以及是否可以安全地假设相同类型的多个promise回调总是按顺序堆叠?
var dfd = $.Deferred(),
    promise = dfd.promise();

promise.done(function(){
    console.log(1);
}).done(function(){
    console.log(2);
});

dfd.resolve();

http://jsfiddle.net/4ax4nxbh/

1个回答

17

这是jQuery中deferred对象的正确和记录使用。文档明确说明:

回调函数按添加顺序执行。

在其他Promise库中,它的工作方式不同,通常更喜欢使用.then而不是.done(稍后在答案中解释)。然而,如果它们是同步的,那么在使用jQuery promises时,它们将按顺序堆叠得很好。

因此,对于您的问题,直接答案是肯定的。

但是,您还可以使用异步代码来完成这项任务,并通过.then更好地链接它:

promise.then(function(){
    console.log(1);
}).then(function(){
    console.log(2);
}).then(function(){
    return $.get(...);
}).then(function(){
    console.log(3); // this always executes after the $.get finishes.
});

基本上,done 添加一个处理程序并返回相同的 Promise,.then 返回从最后一个 Promise 链接的新 Promise。通常我只使用 .done 来终止链式调用,并且如果您想保留返回值(即 function(){ 的参数),则需要使用它。


我希望你能找到这个话题 ;) 当你说“通常情况下,.then比.done更受欢迎”时,我想你指的是链式调用,而不是一般的done和then?根据你的评论,我猜最合适的方法是使用then()后跟一个“终止”的done(),即使在这种情况下我只处理同步代码? - Johan
@Johan,一般情况下,在使用新的 promise 库时,我更喜欢使用 then 而非 done。然而,在 jQuery 中,使用.done 来终止链式调用是有益的。话虽如此,这并不是 jQuery promises 的最大问题。 - Benjamin Gruenbaum
1
同意。感谢您教我两者之间的区别! - Johan
“在其他的 Promise 库中它的工作方����是什么��?Promises/A+ 规范确�指定按照 then() 调用的顺�执行�调函数。(在澄清之�我会等待并�留我的��) - Bergi
在 jQuery 中,.done 接受一个回调函数并返回相同的 promise。在其他库(如 Q 和 Bluebird)中,.done 不接受任何参数,也不返回任何内容。在 jQuery 中,它用于将处理程序链接到结果 - 在其他库中,它终止 promise 链并记录任何未处理的拒绝 - jQuery 在其 promises 中无法很好地处理拒绝。我想这就是我的意思。 - Benjamin Gruenbaum
啊,你的意思是"done的作用不同",而不是"顺序不同"。 - Bergi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接