如何累积来自各种AJAX调用的数据?

时间:2011-06-07 11:52:10

标签: javascript jquery ajax

除了可以认为合适的同步AJAX调用之外,处理这样的事情的最佳方法是什么?

var A = getDataFromServerWithAJAXCall(whatever);
var B = getDataFromServerWithAJAXCallThatDependsOnPreviousData(A);
var C = getMoreDataFromServerWithAJAXCall(whatever2);

processAllDataAndShowResult(A,B,C);

如果我可以将回调传递给那些函数,我知道我可以使用闭包和lambdas来完成这样的工作:

var A,B,C;

getDataFromServerWithAJAXCall(whatever, function(AJAXResult) {
    A= AJAXResult;
    getDataFromServerWithAJAXCallThatDependsOnPreviousData(A, function(AJAXResult2) {
        B= AJAXResult2;
        processAllDataAndShowResult(A,B,C);
    });
});
getMoreDataFromServerWithAJAXCall(whatever2, function(AJAXResult) {
    C= AJAXResult;
    processAllDataAndShowResult(A,B,C);
});

function processAllDataAndShowResult(A,B,C) {
    if(A && B && C) {
        //Do stuff
    }
}

但它对我来说感觉不对或干净。那么有更好的方法或至少更简洁的方式来做同样的事情,还是只是因为我不习惯于javascript函数式编程?

顺便说一下,如果有帮助的话,我正在使用jQuery(1.4.2)。

谢谢。

4 个答案:

答案 0 :(得分:5)

是的,jQuery的Deferred Object非常方便。

以下是$.when()函数documentation中的示例,说明了问题的解决方案:

$.when($.ajax("/page1.php"), $.ajax("/page2.php")).done(function(a1,  a2){
    /* a1 and a2 are arguments resolved for the 
        page1 and page2 ajax requests, respectively */
   var jqXHR = a1[2]; /* arguments are [ "success", statusText, jqXHR ] */
   if ( /Whip It/.test(jqXHR.responseText) ) {
      alert("First page has 'Whip It' somewhere.");
   }
});

干杯!

答案 1 :(得分:0)

如果您可以使用jQuery 1.5,那么您应该可以使用deferred object$.when()

来满足您的需求
$.when(getDataFromServerWithAJAXCall("Call 1"), getMoreDataFromServerWithAJAXCall("Call 2")).done(function(a1, a2) {
    var jqXHR = a1[2];
    jqXHR.responseText;
    getDataFromServerWithAJAXCallThatDependsOnPreviousData(jqXHR.responseText);
});

简单地说,当前两个函数完成时,它将执行第三个函数。

<强> Example on jsfiddle

答案 2 :(得分:0)

使每个AJAX调用的回调函数在一个常见的本地存储中检查/存储结果。并且具有从该容器读取的另一个处理函数,可以定期或由每个回调激活。这样,您可以保持功能清洁并专注于Ajax调用。这也使得累积可以轻松扩展到n个Ajax调用,并且在添加新调用时不必修改现有代码。

答案 3 :(得分:0)

使用所谓的'倒计时锁定'

  1. 每个函数都有自己的回调函数。
  2. 每次调用函数时都会调用一个名为countdownlatch的变量 到达每个回调时倒计时(确保 同时倒计时异步错误。
  3. 每个回调分别检查countdownlatch==0是否调用函数 processAllDataAndShowResult
  4. 使用这些异步同步的javascript的美妙之处在于实现倒计时非常容易,因为javascript是单线程的,即:由于竞争条件,因此countdownlatch无法获得时髦的数字不存在(在这种情况下)。

    修改

    没有看到B依赖于A,但同样的原则适用:

    var A,B,C;
    var cdlatch = 2;
    getDataFromServerWithAJAXCall(whatever, function(AJAXResult) {
        A= AJAXResult;
        getDataFromServerWithAJAXCallThatDependsOnPreviousData(A, function(AJAXResult2) {
            B= AJAXResult2;
            if(--cdlatch === 0){
              processAllDataAndShowResult(A,B,C);
            }
        });
    });
    getMoreDataFromServerWithAJAXCall(whatever2, function(AJAXResult) {
        C= AJAXResult;
        if(--cdlatch === 0){
          processAllDataAndShowResult(A,B,C);
        }  
    });
    
    function processAllDataAndShowResult(A,B,C) {
       //Do stuff
    }
    

    我必须承认,这不像我之前描述的一般情况那样清楚,哦。