如何从JavaScript函数返回一个Promise?

3
想象一下,我有三个函数X、Y和Z,它们都返回承诺并准备好进行链式操作。我的目标是在它们完成之后通知进度并处理错误。以下哪种写法更好,为什么(有何影响):
A.
function my_func(index, size){
    return X
        .then(Y)
        .then(Z)
        .then(
           function(data){
               var dfd = new $.Deferred();
               dfd.notify("progress", index / size, 'OK');
               dfd.resolve(data);
               return dfd.promise();
           },
           function(){
               return handleError(arguments, size, index);
           }
        );
}

或者
function my_func(index, size){
    var dfd = new $.Deferred();
    X
    .then(Y)
    .then(Z)
    .then(
        function(data){
            dfd.notify("progress", index / size, 'OK');
            dfd.resolve(data);
        },
        function(){
            return handleError(arguments, size, index);
        }
    )
    return dfd.promise();
}

此外,以下两者有何不同:
X.then(Y).then(Z);

并且:

$.when(X).then(Y).than(Z);

如果$.when部分是不必要的,那么为什么jQuery中还会存在它?

评论已从@Benjamin Gruenbaum的评论中删除。 - John Skoumbourdis
你是对的。对此感到抱歉! - John Skoumbourdis
2个回答

0
后者是不必要的。这只是额外的冗余代码。$.when 对于将值转换为承诺和聚合非常有用。
以下是一个平均的$.when使用案例:
$.when($.get(...),$.get(...)).then(function(firstResult,secondResult){
     // access both results here
}); 

你可以在这里使用两个结果,它们都已经完成。

至于第一个问题 - 基本上是B。第一个选项是deferred anti pattern,最好避免使用。请参阅关于此的链接问题。


谢谢您的解释,那么我的问题的第一部分呢? - mnowotka
同意@BenjaminGruenbaum的观点,第二种方法似乎更加简洁,因为my_func函数正确地包装了内部发生的事情。但是......总的来说,我认为您错误地认为.then()链接将按照那个顺序进行操作,只有在Y被解决后,才会发生Z。这不是事实,在两种情况下,所有的.then()都发生在X解决时。我也曾有过这样的印象,但请参见此JSFiddle(按第二个按钮):http://jsfiddle.net/vH84q/1/(编辑:打开浏览器控制台以查看发生的情况)。 - UweB

0
主要的区别在于您依赖于 X 是一个具有方法 then 的对象。 将非 Deferred/promise 对象传递给 $.when 将把它视为已解决的 Deferred,个人而言,我更喜欢这种方式,因为它使函数之间的耦合更加松散。

一个更准确的术语可能是“已完成”,它将把它视为已完成的延迟。 - Benjamin Gruenbaum
我同意,但实际上我是引用了jQuery API文档中的内容 ;) "...它将被视为已解决的Deferred...", 请参阅http://api.jquery.com/jQuery.when/。 - UweB
相同的评论在这里 - 我很感激对when使用方法的解释,但对我来说问题的第一部分更重要 :) - mnowotka

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