Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/461.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 更好的方法来处理JQuery$中数量可变的延迟请求。何时调用?_Javascript_Jquery_Json_Jquery Deferred_.when - Fatal编程技术网

Javascript 更好的方法来处理JQuery$中数量可变的延迟请求。何时调用?

Javascript 更好的方法来处理JQuery$中数量可变的延迟请求。何时调用?,javascript,jquery,json,jquery-deferred,.when,Javascript,Jquery,Json,Jquery Deferred,.when,我正在编写一个应用程序,在某一点上需要在继续之前获得一些请求的结果。这似乎是在时使用JQuery的的一个可能的候选。例如: // requests is an array of Deferreds $.when.apply(null, requests).done(function(results) { // process results } 问题在于请求的数量可以是1,也可以更多,而when函数处理这些情况的方式不同。只有一个请求时,回调会获取标准(data、textSta

我正在编写一个应用程序,在某一点上需要在继续之前获得一些请求的结果。这似乎是在时使用JQuery的
的一个可能的候选。例如:

 // requests is an array of Deferreds
 $.when.apply(null, requests).done(function(results) {
     // process results
 }
问题在于请求的数量可以是1,也可以更多,而
when
函数处理这些情况的方式不同。只有一个请求时,回调会获取标准(data、textStatus、jqXHR)参数,但是当提供多个请求时,回调会接收一系列参数:每个请求的(data、textStatus、jqXHR)值数组。令人沮丧的是,JQuery似乎将单例请求数组视为单参数请求,这意味着必须以不同的方式处理这种情况

我所能想出的最好的办法是把这些情况分开,这让我觉得有点笨拙,而且由于不同情况下的结果参数的微妙性,我花了一段时间才弄清楚,然后,请求数组的新手需要包装在一个函数中,以便在闭包中访问它

$.when.apply(null, function (){return requests;}()).done(function(results) {
    if (requests.length == 1) {
        processResults(results);
    } else {
        for (var i=0; i < arguments.length; i++)
            processResults(arguments[i][0]);
    }
   moreStuff();
});
$.when.apply(null,函数(){return requests;}()).done(函数(结果){
if(requests.length==1){
处理结果(结果);
}否则{
for(var i=0;i

有比这更好或更优雅的方法吗?

我知道这是一个老问题,但最近我遇到了这个问题,我在搜索这个问题时遇到了这个问题。我最终创建了自己的解决方案,所以我想在这里分享它作为一个答案

简言之,
$.when()
的设计并不能很好地用于动态数量的参数。事实上,动态参数有点糟糕。它既难以使用,又行为不一致

ES6 promises规范的设计者似乎同意这一点,因为那里的模拟
Promise.all()
设计不同,解决了这两个问题。因此,我能想到的处理jQuery的
$.when()
问题的最好办法是制作一个新版本,它遵循
Promise.all()
规则,因此使用起来更简单。jQuery Ajax承诺返回一个包含三个值的数组,这些值以您提到的奇怪方式与
$.when()
交互,这让生活变得更加复杂

因此,对
$有两个主要更改。when()
要生成
$。all()

  • 使其接受一系列承诺,而不是承诺的单独参数。这使您不必只使用
    .apply()
    $.all()
    发送数量可变的承诺

  • 使结果表单
    $。无论最初传递了多少个承诺,all()
    始终是数组形式。这就是你在问题中提出的前后矛盾。幸运的是,修复这个问题不需要很多代码

  • 可以这样做:

    $.all = function (promises) {
        if (!Array.isArray(promises)) {
            throw new Error("$.all() must be passed an array of promises");
        }
        return $.when.apply($, promises).then(function () {
            // if single argument was expanded into multiple arguments, then put it back into an array
            // for consistency
            if (promises.length === 1 && arguments.length > 1) {
                // put arguments into an array
                return [Array.prototype.slice.call(arguments, 0)];
            } else {
                return Array.prototype.slice.call(arguments, 0);
            }
        })
    };
    
    您使用它就像
    $.when()
    一样,只是您总是传递
    $.all()
    一个作为承诺数组的单个参数(不再需要
    .apply()
    ),并且它总是解析为一个作为结果数组的单个参数(更容易迭代承诺结果的动态数量,并且总是一致的).

    因此,如果您有一个任意长度的ajax承诺数组:

    var promises = [url1, url2, url3].map(function(url) {
        return $.get(url);
    });
    
    
    $.all(promises).then(function(results) {
        // results are always consistent here no matter how many promises
        // were originally passed in, thus solving your original problem
        for (var i = 0; i < results.length; i++) {
            console.log(results[i]);
        }
    });
    
    var promises=[url1,url2,url3].map(函数(url){
    返回$.get(url);
    });
    $.all(承诺)。然后(函数(结果){
    //无论有多少承诺,结果总是一致的
    //是最初传入的,因此解决了您最初的问题
    对于(var i=0;i
    我有一个类似的情况,我有固定数量的唯一延迟请求,但根据具体情况,我不想进行所有这些调用,因此,我不想处理所有响应。我的方法是创建一个返回空响应的虚拟延迟

    // this immediately returns whatever 
    // is passed in as response
    function emptyAjaxResponse(response) {
        var deferred = $.Deferred().resolve(response);
        return deferred.promise();
    }
    
    function multipleAjaxCalls(someCondition) {
    
        // promise1 always needs to happen
        var promise1 = jQuery.getJSON("some url");
    
        // promise2 is always an array, but if someCondition is
        // not met, we won't bother to make the actual request,
        // just feed in an empty array.
        var promise2 = someCondition ? jQuery.getJSON("some other url") : emptyAjaxResponse([]);
    
        $.when(promise1, promise2).done(response1, response2) {
            // now, we can process response1 and response2
            // appropriately whether we made an actual ajax
            // call on promise2 or not.
        }
    }
    

    当然,在发布之后,我马上想到了一个比较明显的答案,即对于n==1的情况,这里不
    where
    。这方面有什么进展吗?为什么要将函数作为第二个参数传递给
    when.apply
    这不是一种改进,而是一种稍微不同的方法
    $.when.apply($,requests).then(function(results){if(requests.length==1){return[results];}else{return$.map(results,function(args){return args[0];});}}}).done(函数(结果){$.each(结果,函数(结果){processResults(结果);});moreStuff();})
    如果没有这个,请求数组在闭包中是未定义的。我想是因为数组在JavaScript中是按值传递的。我知道JavaScript中有闭包,所以我在这里很可能是错的。你能分享发出调用的out函数吗?你也看了上面的代码片段吗