【问题标题】:jQuery Deferred.then - failFilter argumentjQuery Deferred.then - failFilter 参数
【发布时间】:2015-12-17 10:07:26
【问题描述】:

我正在尝试了解 jQuery deferred/promises(使用 v1.8+)。

通过阅读文档,$.Deferred.then(...) 方法接受 doneFilterfailFilter 作为要执行的参数,并返回一个 Promise,我们可以使用它进行如下链接:

function doDefer() {
    var $defer = $.Deferred();

    doSomethingAsynchronous(
        function () {
            $defer.resolve();
        },
        function () {
            $defer.reject();
        }
    );

    return $defer.promise();
}

doDefer()
    .then(function () {
        return;
    }, function () {
        // second `then` not called
    })
    .then(function (b) {
        // `b` is undefined, since first `then` returned without a value.
    }, function () {
        // fail end
    });

两个问题:

  1. 如果遇到第一个fail 函数,为什么执行链会在doDefer() 处停止?据我了解,then 返回一个$.Deferred.promise(),这是第二个then 函数链接(并执行)的方式。第一个链中的then doneFilter/function/callback 总是返回(?) - 那么为什么/如何 jQuery 以不同的方式处理failFilter
  2. 为什么then返回一个$.Deferred.promise(),而done/always/fail等返回一个$.Deferred?这有什么用(为什么它与then 不同)?

【问题讨论】:

  • 不,它工作得很好。我创建了一个小提琴:jsfiddle.net/oy95nh47/1 如果你调用“resolve”,“done”会显示两次。如果调用“reject”,“fail”会显示两次。
  • 嗯,现在可以了。如果随时调用fail,有没有办法退出链?

标签: javascript jquery promise jquery-deferred


【解决方案1】:

如果遇到第一个fail 函数,为什么执行链会在doDefer() 处停止?据我了解,then 返回一个承诺,这是第二个then 函数链接(并执行)的方式。第一个链中的then done 回调总是返回(?) - 那么为什么/如何 jQuery 以不同的方式处理 failFilter

我不确定我是否理解正确,但有两件事你应该知道:

为什么then 返回$.Deferred.promise()

因为它是一个承诺,将通过相应回调的结果来解决。您可以自行解决,这不是延迟。另见What are the differences between Deferred, Promise and Future in JavaScript?

...但是done/always/fail 等返回$.Deferred

他们没有。他们只是返回他们被调用的对象,不管它是一个承诺还是延迟。

【讨论】:

    【解决方案2】:

    你可以看到这个例子,它的工作正常:

    function doDefer() {
        var $defer = $.Deferred();
    
        setTimeout( function(){
                    doSomethingAsynchronous(
                        function ( value ) {
                            // func1 - value is a random number
                            $defer.resolve( value );
                        },
                        function () {
                            $defer.reject();
                        }
                    );
                }, 1000 );
    
        return $defer.promise();
    }
    
    function doSomethingAsynchronous( func1, func2 ){
        // random number 0-10
        var random = Math.round( Math.random()*10 )
        if( random > 5 ){
            return func1.call( this, random );
        }else{
            return func2.call( this );
        }
    }
    
    doDefer().then(function ( value ) {
        // success
        // make double of random
        return value*2;
    }, function () {
        // fail when random number < 5
    })
    .then(function (b) {
        // `b` is double of random number
        console.log(b);
    }, function () {
        // fail end
    });
    

    希望对你有帮助

    【讨论】:

      【解决方案3】:

      failHandler 会像你说的那样停止执行。关键是看链条。只有当它被链接到的 Promise 被拒绝时,失败处理程序才会执行。确保您将链中的每个环节都视为单独的承诺。

      链接可以改写如下。

      dfd1 = doDefer();
      
      dfd2 = dfd1.then( success1, fail1 );
      
      dfd3 = dfd2.then( success2, fail2 );
      

      在这个例子中,success1 只有在 dfd1 被解析时才会被调用。如果它被拒绝,fail1 将被调用并且链将停止。

      同样,success2 只会在 dfd2 被解析时被调用(换句话说,success1 返回一个值或解析一个返回的承诺)。执行fail2 的唯一方法是,如果dfd2success1 明确拒绝(错误冒泡在jQuery 的实现中不起作用)。

      tl;dr - 失败不链接,正如@Bergi 所说,jQuery 中的错误处理被破坏了

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-07-31
        • 1970-01-01
        • 2012-09-09
        • 2018-09-29
        • 1970-01-01
        • 2011-12-12
        • 1970-01-01
        相关资源
        最近更新 更多