Javascript:有没有更好的方法在x次异步数据库/ ajax调用后执行函数

Javascript: is there a better way to execute a function after x amount of async database/ajax calls

本文关键字:ajax 数据库 调用 函数 执行 异步 更好 有没有 方法 Javascript      更新时间:2023-09-26

使用Backbone.js我们有一个应用程序,在某些情况下我们需要将ajax帖子发送到客户端Web服务。

但是,要发布的内容是动态的,并且由某个数组决定。

对于数组中的每个项目,我们需要获取一条数据。

组装数据后,需要发送聚合对象。

截至目前,我有一个同步方法,尽管我觉得这不是最好的方法。

var arrParams = [{id: 1, processed: false},{id: 7, processed: false},{id: 4, processed: false}];
function callback(data) {
    $.post()... // jquery ajax to post the data... }
function fetchData(arr, data, callback) {
    var currentId = _(arr).find(function(p){ return p.processed === false; }).id;  // getting the ID of the first param that has processed on false...
    // ajax call fetching the results for that parameter.
    $.ajax({
        url: 'http://mysuperwebservice.com',
        type: 'GET',
        dataType: 'json',
        data: {id: currentId},
        success: function(serviceData) {
            data[currentId] = serviceData;  // insert it into the data
            _(arr).find(function(p){ return p.id === currentId; }).processed = true; // set this param in the array to 'being processed'.
            // if more params not processed, call this function again, else continue to callback
            if(_(arr).any(function(p){ return p.processed === false }))
            {
                 fetchData(arr, data, callback);
            }
            else
            {
                callback(data);
            }
        },
        error: function(){ /* not important fr now, ... */ }
    }); 
}
fetchData(arrParams, {}, callback);

有没有办法异步启动这些调用并仅在所有结果都输入时才执行回调?

你必须

使用JQuery $.Deferred对象来同步它们。查看这篇文章 延迟文档

您可以通过以下方式使用:

$.when(
   $.ajax({ url : 'url1' }),
   $.ajax({ url : 'url2' }) // or even more calls
).done(done_callback).fail(fail_callback);

我会做这样的事情:

创建一个函数,除了传递给 fetchData 的参数之外,它还获取 arrParams 中的索引,然后在循环中为每个元素调用该函数。在成功函数中,将元素中处理的设置为 true,并通过遍历数组来检查"你是最后一个",看看其余部分是否也都为 true。

如果您制作计数器,则可以进行一些优化:

var todo = arrParams.length;

在成功中,您做到了:

if (--todo == 0) {
   callback(...)
}