Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 当(…)不考虑最终状态时,是否有方法检查美元承诺的个人结果_Javascript_Jquery_Ajax_Deferred - Fatal编程技术网

Javascript 当(…)不考虑最终状态时,是否有方法检查美元承诺的个人结果

Javascript 当(…)不考虑最终状态时,是否有方法检查美元承诺的个人结果,javascript,jquery,ajax,deferred,Javascript,Jquery,Ajax,Deferred,检查以下示例 $.when(a1, a2, a3, a4, .....) .done(function (){alert('done')}) .fail(function (){alert('fail')}); 如果所有a1 ax都成功,我可以检索和处理“完成”函数中所有“承诺”的所有数据 如果a1和a2失败,而a3和a4成功并返回一些数据。“fail”被调用,并没有说明实际失败的内容,也没有传递成功的值(不传递任何参数) 问题 有没有办法通过“延迟”(即使失败)检

检查以下示例

$.when(a1, a2, a3, a4, .....)
       .done(function (){alert('done')})
       .fail(function (){alert('fail')});
如果所有a1 ax都成功,我可以检索和处理“完成”函数中所有“承诺”的所有数据

如果a1和a2失败,而a3和a4成功并返回一些数据。“fail”被调用,并没有说明实际失败的内容,也没有传递成功的值(不传递任何参数)

问题 有没有办法通过“延迟”(即使失败)检索成功调用(a3和a4)的值(数据),或者我应该为此为每个承诺分配单独的回调?

$。when()
被设计为在传递给它的任何承诺被拒绝时立即执行
.fail()
。因此,如果a1或a2被拒绝,它将调用
.fail()
,并且可能还没有a3和a4的数据。这就是它的设计方式,在某些情况下确实限制了它的实用性。如果您想知道每个单独的结果,而不管其他承诺是否失败,并且您正在使用
$.when()
,那么正如您所猜测的,您需要将自己的
.done()
.fail()
处理程序附加到每个单独的承诺

巧合的是,我实现了一个多延迟对象(供我自己使用),它允许您指定如果任何承诺失败(如
$.when()
所做的),是希望它立即失败,还是等到所有承诺都达到最终结果后再调用master
.fail()
.done()
。这可能对你有用

这是功能与
$之间差异的总结。when()

  • 您可以将其配置为在使用
    .setFailImmediate(false)
    方法完成所有承诺之前不调用自己的
    .fail()
  • 它有一个
    .add()
    方法,因此您可以向它添加更多承诺(在解决之前)。由于这些承诺通常在一个循环中收集,因此只需
    .add()
    一个承诺,而不是将它们全部收集在一个数组中,然后传递给
    $.when()
  • .progress()
    的工作原理不同。这不会重复每个承诺的
    .progress()
    ,而是执行
    .notify()
    ,在每个承诺被拒绝或解决时触发
    .progress()
    ,以便跟踪每个承诺的完成情况。如果你想要每个承诺的实际进展,你可以直接附加到它们上
  • 您可以随时使用
    .getFailYet()
    查询延迟的承诺是否已失败
  • 您可以使用
    .getRemaining()
    查询有多少承诺尚未完成
  • 请注意,构造函数
    $.MultiDeferred()
    返回一个实际的延迟对象(添加了一些额外的方法),您还可以对其调用
    .promise()
    ,以仅获取promise对象(该对象上也会有额外的方法)

    MultiDeferred
    对象可以这样使用:

    var d = $.MultiDeferred(a1, a2, a3, a4);
    // configure it to not fail immediately when any single promise fails
    d.setFailImmediate(false);
    // you can optionally add more promises here
    // often in a loop
    d.add(a5, a6);
    d.done(function() {
        // called when all promises have been successfully resolved
    }).fail(function() {
        // even if one promise failed, all the data from all the promises
        // is passed here as this can be configured to wait for all
        // promises to finish before calling .fail()
    });
    
    工作演示:

    多重延迟对象的代码如下所示:

    jQuery.MultiDeferred = function(/* zero or more promises */) {
    
        // make the Deferred
        var self = jQuery.Deferred();
        // get the promise so new methods can be added to it too
        var promise = self.promise();
    
        var remainingToFinish = 0;
        // two parallel arrays that contain the promises that are added
        // and the arguments passed to reject() or resolve()
        // so when we call the master reject() or resolve(), we can pass all those args on through
        var promises = [];
        var args = [];
    
        // keep track of what to do upon failure and whether we had any failures
        var anyFail = false;
        var failImmediate = false;
    
        function _add(p) {
            // save our index in a local variable so it's available in this closure later
            // so we know what the array index was of this particular promise when it fires
            var index = promises.length;
    
            // save this promise into our array structure
            promises.push(p);
            // push placeholder in the args array
            args.push([null]);
    
            // one more waiting to finish
            ++remainingToFinish;
    
            // see if all the promises are done
            function checkDone(fail) {
                return function() {
                    anyFail |= fail;
                    // make copy of arguments so we can save them
                    args[index] = Array.prototype.slice.call(arguments, 0);
                    --remainingToFinish;
    
                    // send notification that one has finished
                    self.notify.apply(self, args[index]);
                    // if all promises are done, then resolve or reject
                    if (self.state() === "pending" && (remainingToFinish === 0 || (fail && failImmediate))){
                        var method = anyFail ? "reject" : "resolve";
                        self[method].apply(self, args);
                    }
                }
            }
            // add our own monitors so we can collect all the data
            // and keep track of whether any fail
            p.when(checkDone(false), checkDone(true));
        }
    
        self.add = function(/* one or more promises or arrays of promises */) {
            if (this.state() !== "pending") {
                throw "Can't add to a deferred that is already resolved or rejected";
            }
            var arg;
            for (var i = 0; i < arguments.length; i++) {
                // if the next arg is not an array, then put it in an array
                // so the rest of the code can just treat it like an array
                arg = arguments[i];
                if (!Array.isArray(arg)) {
                    arg = [arg];
                }
                for (var j = 0; j < arg.length; j++) {
                    _add(arg[j]);
                }
            }
            return this;
        }
    
        // set whether the deferred should reject immediately if any subordinate
        // promises fails or whether it should wait until all have completed
        // default is to wait until all have completed
        self.setFailImmediate = function(failQuick) {
            failImmediate = failQuick;
            return this;
        }
    
        // only query methods are on the promise object 
        // get count of remaining promises that haven't completed yet
        self.getRemaining = promise.getRemaining = function() {
            return remainingToFinish;
        }
    
        // get boolean on whether any promises have failed yet
        self.getFailYet = promise.getFailYet = function() {
            return anyFail;
        }
    
        // add any promises passed to the constructor
        self.add.apply(self, arguments);
        return self;    
    };
    
    jQuery.MultiDeferred=函数(/*零个或多个承诺*/){
    //延期交货
    var self=jQuery.Deferred();
    //获得承诺,这样新方法也可以添加到其中
    var promise=self.promise();
    var remainingToFinish=0;
    //包含添加的承诺的两个并行阵列
    //以及传递给reject()或resolve()的参数
    //因此,当我们调用master reject()或resolve()时,我们可以通过
    var承诺=[];
    var args=[];
    //跟踪失败后要做什么,以及我们是否有任何失败
    var anyFail=false;
    var=false;
    功能添加(p){
    //将索引保存在局部变量中,以便稍后在此闭包中可用
    //所以我们知道当它触发时,数组索引是什么
    var指数=1.5倍长度;
    //将此承诺保存到我们的数组结构中
    承诺推送(p);
    //在args数组中推送占位符
    参数推送([null]);
    //还有一个等待完成
    ++保持完美;
    //看看是否所有的承诺都兑现了
    功能检查完成(失败){
    返回函数(){
    anyFail |=失败;
    //复制参数以便保存它们
    args[index]=Array.prototype.slice.call(参数,0);
    --保持完美;
    //发送已完成的通知
    self.notify.apply(self,args[index]);
    //如果所有的承诺都完成了,那么就决定还是拒绝
    if(self.state()==“pending”&&(remainingToFinish===0 | |(fail&&failImmediate))){
    var method=anyFail?“拒绝”:“解决”;
    self[method].apply(self,args);
    }
    }
    }
    //添加我们自己的监视器,以便收集所有数据
    //并记录是否有任何失败
    p、 when(checkDone(false)、checkDone(true));
    }
    self.add=函数(/*一个或多个承诺或承诺数组*/){
    if(this.state()!==“待定”){
    抛出“无法添加到已解决或已拒绝的延迟”;
    }
    var-arg;
    for(var i=0;i