使用$ .when()和.then根据$ .getJSON响应更新数组

时间:2012-01-11 22:16:28

标签: javascript jquery

我正在尝试使用来自多个getJSON请求的响应来更新数组值。我尝试了很多方法,下面的代码片段是我用过的最简单的形式。在.then()触发时,各个成功回调没有更新数组,因此警报显示原始值。我还尝试将各个jqXHR对象存储在一个数组中并完成它们,但它们都是readyState:1。有关如何在响应完成后获取对响应的引用的任何建议吗?

$(function() {

    var points = [['A', 12946],
                  ['B', 4223],
                  ['C', 2774],
                 ];

    function makePointCalls(i) {
        return $.getJSON("http://otter.topsy.com/searchcount.json?callback=?",
            {
                q: points[i][0]
            },
            function(data) {
                points[i][1] = data.response.d;
            }
        );
    }

    $.when($.each(points, function(i, value){
              makePointCalls(i);
            })
        ).then(function(){
            //alert me after all the getJSONs are done and array updated?
            alert(points);
        });
});//doc ready

2 个答案:

答案 0 :(得分:2)

$.each(...)替换为$.map(...).get(),并将makePointCalls(i)替换为return makePointCalls(i)

$(function() {

    var points = [['A', 12946],
                  ['B', 4223],
                  ['C', 2774],
                 ];

    function makePointCalls(i) {
        return $.getJSON("http://otter.topsy.com/searchcount.json?callback=?",
            {
                q: points[i][0]
            },
            function(data) {
                points[i][1] = data.response.d;
            }
        );
    }

    $.when($.map(points, function(i, value){
              return makePointCalls(i);
            }).get();
        ).then(function(){
            //alert me after all the getJSONs are done and array updated?
            alert(points);
        });
});//doc ready

答案 1 :(得分:2)

您的代码需要对makePointCalls循环中丢弃的each的返回值做出反应。

未经测试的代码片段(根据kas673的评论工作):

// Collect deferreds first
var deferreds = jQuery.map(points, function(i, value){
    return makePointCalls(i);
});

// Pass all deferreds to when
jQuery.when.apply(jQuery, deferreds).then(…);

请注意使用map代替each来创建一个返回值(延迟)为makePointCalls的数组。调用apply调用when是为了确保when收到parameters in the documented format。如果您将一个数组作为唯一参数传递给when,它可以假设它已收到已解决的延迟并立即在then中执行该函数。

关于apply的使用的更详细的解释是when假定所有内容都是一个不是延迟的已解决的延迟。首先需要注意的是延迟是某种回调管理器。它保存回调以调用成功/解析和回调失败/拒绝。延迟用于提供返回值,只有在稍后才知道函数调用是否成功。一个例子是您的AJAX请求需要等待服务器,但不应阻止JavaScript执行。

您对$.getJSON的每次调用都会返回延迟,可用于对请求完成做出反应。 $.when将任意数量的延迟作为参数,并在知道延迟的聚合状态时立即调用then的参数(当when的所有参数都被解析时或至少一个被拒绝了。)

$.when(deferreds).then(callback)作为callback对象数组时,调用deferreds会导致立即调用Deferred。当聚合状态已知时,调用$.when(deferred[0], deferred[1]).then(callback)会调用callback。使用apply允许您解压缩数组并使用数组中的每个元素作为调用apply的函数的参数(在您的情况下为when)。

再次检查您的ActiveX通知,因为Firebug在Firefox中运行,幸运的是,不支持ActiveX。任何与ActiveX相关的东西都可能是因为你使用的是一个不应该使用Microsoft的API。