【问题标题】:jQuery Deferred - getting result of chained ajax callsjQuery Deferred - 获取链式 ajax 调用的结果
【发布时间】:2012-12-04 11:12:40
【问题描述】:

以下问题 - 我必须多次调用 ajax 函数,当所有函数完成后,将所有结果放入数组中。我想出了这个:

function doAjax(xx){
var xdata = {json: $.toJSON({name: xx}),
            delay: 1};
return $.ajax({
    url:"/echo/json/",
    data:xdata,
    type:"POST"
});

}

var carr = [doAjax('a'),doAjax('b'),doAjax('c'),doAjax('d')]
var result = [];

$.when( carr )
    .done(function(data){
        console.log(data);
        $.each(data, function(ix,val){
            console.log(val.name);
        });
    });

在这里提琴:http://jsfiddle.net/Fkd9n/

似乎一切正常,“console.log(data)”用响应文本写出对象,但“console.log(val.name)”总是“未定义”。那么如何在所有调用完成后将所有结果合并到一个数组中呢?

谢谢!

【问题讨论】:

  • $.when() 不能接受延迟数组
  • 你也可以这样FIDDLE ...
  • @adeneo: Uncaught TypeError: Cannot read property 'name' of undefined

标签: jquery ajax deferred


【解决方案1】:

如果您知道有多少个 Ajax-Call,只需使用 $.when()

$.when(doAjax('a'),doAjax('b'),doAjax('c'),doAjax('d'))
.then(function(result_a,result_b,result_c,result_d) {
    console.log("Result from query a: " + result_a);
    console.log("Result from query b: " + result_b);
    console.log("Result from query c: " + result_c);
    console.log("Result from query d: " + result_d);
});

如果您不知道将有多少个 ajax 调用,您可以自己管理延迟对象。

// altered version of doAjax()
function doAjax(number,dObject) {
    var xdata = {json: $.toJSON({name: number}), delay: 1};
    $.ajax({
        url:"/echo/json/",
        data:xdata,
        type:"POST",
        success: function(data) {
            results.push(data);
            dObject.resolve();
        }
    });
}

// array that will contain all deferred objects
var deferreds = [];

// array that will contain all results
var results = [];

// make the ajax calls
for (var i = 0; i < someNumber; i++) {
    var dObject = new $.Deferred();
    deferreds.push(dObject);
    doAjax(i,dObject);
}

// check if all ajax calls have finished
$.when.apply($, deferreds).done(function() {
    console.log(results);
});

函数 apply() 带来了神奇的功能,它为函数的参数创建一个数组。

【讨论】:

  • 虽然有些错别字;)我喜欢这个解决方案。感谢您的快速答复!
  • 您在哪里找到错别字?顺便说一句,我也是来自瑞士的 Markus :)
  • 真是巧合! :D 无论如何,没什么大不了的,只是“.done”函数中缺少右括号。再次感谢您!
【解决方案2】:

您可以使用pipe 函数来处理结果数据。

$.when.apply($, carr).pipe(function(){
    console.log(arguments);
    return $.map(arguments, function(item){return item[0]});
})
    .done(function(data){
        console.log(data);
        $.each(data, function(ix,val){
            console.log(val.name);
        });
    });​

http://jsfiddle.net/Fkd9n/6/

【讨论】:

  • 非常感谢您的解决方案,它按预期工作,我喜欢它的简单性。但是我会接受“Zim84”的答案,因为它更符合我的需求。
  • 仅供参考:从 jQuery 1.8 开始,不推荐使用 deferred.pipe() 方法。应该使用替代它的 deferred.then() 方法。 deferred.pipe
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-06
  • 1970-01-01
相关资源
最近更新 更多