有序异步AJAX调用

时间:2012-02-22 19:54:03

标签: javascript jquery

我正在创建一个执行多个功能的脚本,我想在功能完成时更新用户。我在前一个调用的$.ajax()块中的每个后续调用都嵌套了success次调用。

每个循环总共进行4次调用。让我们通过scan_1给他们打电话scan_4success的{​​{1}}块会调用scan_1,依此类推。

例如,假设我循环了3个对象。我希望这个过程如下:

循环1

  • SCAN_1
  • scan_2
  • scan_3
  • scan_4

循环2

  • SCAN_1
  • scan_2
  • scan_3
  • scan_4

循环3

  • SCAN_1
  • scan_2
  • scan_3
  • scan_4

问题在于它首先在所有scan_2次调用中运行。我必须遗漏一些东西,但我似乎无法弄明白。任何建议都将不胜感激。

作为参考,这里有一段scan_1(不相关的东西剪掉):

scan_1

思想?

提前致谢。

5 个答案:

答案 0 :(得分:3)

听起来你需要to use jQuery deferred。它基本上允许您将多个事件处理程序链接到jQuery Ajax对象,并让您更好地控制何时调用回调。

进一步阅读:

答案 1 :(得分:1)

它是异步的 - "成功"将来某个时候会发生火灾。脚本不会等待它响应。由于您在循环中触发了三个请求,因此它们都将是" scan1"。

" scan_2"将在每个请求完成时调用。

如果要控制事件的顺序,请将请求更改为同步。

答案 2 :(得分:1)

您首先要一次发送三个ajax电话。

Scan1(循环1)
Scan1(循环2)
Scan1(循环3)

当每个扫描1完成时,它会跟随扫描2,然后调用扫描3。

你真的想要发生什么?扫描循环1的1 2和3,然后循环2的1 2和3,然后循环3的1 2和3?这将需要更多嵌套,或者可能需要延迟对象。

答案 3 :(得分:1)

不是对每个success调用使用$.ajax()回调,而是可以将每组AJAX请求(它们的jqXHR对象)存储在一个数组中,并等待所有这些请求解析:

function scan_1 () {

    //setup array to store jqXHR objects (deferred objects)
    var jqXHRs = [];
    for(var i = 1; i <= 3; i++)
    {

        //push a new index onto the array, `$.ajax()` returns an object that will resolve when the response is returned
        jqXHRs[jqXHRs.length] = $.ajax({
            type:       'GET',
            url:        url,
            data:       'do=scan&step=1&' + string,
            dataType:   'json'
        });
    }

    //wait for all four of the AJAX requests to resolve before running `scan_2()`
    $.when(jqXHRs).then(function () {
        if(result.proceed == 'true') {
            scan_2();
        }
    });
}

答案 4 :(得分:0)

我在使用SharePoint Web服务方面遇到过类似的问题 - 您经常需要从多个来源提取数据,以便为单个进程生成输入。

为了解决这个问题,我将这种功能嵌入到我的AJAX抽象库中。您可以轻松定义一个请求,该请求将在完成时触发一组处理程序。但是,每个请求都可以使用多个http调用进行定义。这是组件(和详细文档):

DPAJAX at DepressedPress.com

这个简单的例子创建了一个带有三个调用的请求,然后将这些信息按照调用顺序传递给一个处理程序:

    // The handler function 
function AddUp(Nums) { alert(Nums[1] + Nums[2] + Nums[3]) }; 

    // Create the pool 
myPool = DP_AJAX.createPool(); 

    // Create the request 
myRequest = DP_AJAX.createRequest(AddUp); 

    // Add the calls to the request 
myRequest.addCall("GET", "http://www.mysite.com/Add.htm", [5,10]); 
myRequest.addCall("GET", "http://www.mysite.com/Add.htm", [4,6]); 
myRequest.addCall("GET", "http://www.mysite.com/Add.htm", [7,13]); 

    // Add the request to the pool 
myPool.addRequest(myRequest); 

请注意,不像许多提供的此方法不会强制调用单线程的其他解决方案被提出 - 每个仍将运行尽可能快(或慢)的环境允许,但单个处理程序才会被调用时,所有完成了。它还支持设置超时值和重试尝试,如果您的服务有点冒险。

我发现它非常有用(从代码的角度来理解它非常简单)。没有更多的链接,不再计算呼叫和节省输出。只需“设置并忘记它”。