jQuery Deferred.then - failFilter argument

jQuery Deferred.then - failFilter argument

本文关键字:failFilter argument then Deferred jQuery      更新时间:2023-09-26

我正试图了解jQuery递延/承诺(使用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/函数/回调总是返回(?)-那么jQuery为什么/如何以不同的方式处理failFilter
  2. 为什么then返回$.Deferred.promise(),而done/always/fail等返回$.Deferred?这有什么用(为什么它与then不同)

如果执行链命中第一个fail函数,为什么它会在doDefer()中停止?据我所知,then返回一个promise,这就是第二个then函数的链接(和执行)方式。第一个链中的then回调总是返回(?)-那么jQuery为什么/如何以不同的方式处理failFilter呢?

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

  • then(done, fail)只执行其中一个回调,这取决于它们所链接的承诺是实现还是被拒绝
  • jQuery中的错误处理已完全中断。回调确实按预期进行了调用,但.then(…)调用返回的promise行为不符合Promises/A+。等待jQuery3.0,使用一个合适的promise库(在它之上),或者学会使用它

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

因为这是一个承诺,将通过相应的回调结果来解决。这不是一个你可以自己解决的延期。另请参阅JavaScript中的Deferred、Promise和Future之间的区别是什么?

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

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

您可以看到这个例子,它的工作原理是:

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
});

我希望这能帮助你

failHandler将像您所说的那样停止执行。关键是要看链条。失败处理程序只有在其链接到的Promise被拒绝时才会执行。确保你把链条上的每一个环节都看作是一个单独的承诺。

链接可以重写如下。

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

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

同样,只有在dfd2被解析(换句话说,success1返回值或解析返回的promise)时,才会调用success2。执行fail2的唯一方法是success1显式拒绝dfd2(错误冒泡在jQuery的实现中不起作用)。

tl;dr-fails不连锁,正如@Bergi所说,jQuery 中的错误处理已中断