【问题标题】:Making multiple ajax requests synchronously同步发出多个ajax请求
【发布时间】:2015-03-12 12:54:07
【问题描述】:

假设我有一个名为 makeRequest() 的函数,它向服务器发出 AJAX 请求。

现在让我们假设我知道应该发出这个请求的次数,但我不能异步执行它们,而是同步执行。

例如,给我数字 5,我将调用 makeRequest(),当它完成后,我将再次调用它,当它完成时,我将再次调用它......我应该最终调用它5次。

我不是 JavaScript 专家,但我发现通过使用回调来处理异步调用很容易。

所以,我的makeRequest() 函数采用callback 参数,该参数将在请求成功时执行。

在我之前的示例中,我必须发出 5 次请求,因此行为应该如下所示:

makeRequest(function () {
     makeRequest(function () {
        makeRequest(function () {
           makeRequest(function () {
              makeRequest(function () {
              });
           });
        });
     });
});

我如何设计它以使其对提供给我的 任何 参数(无论是 6、12 还是 1)表现相同?

PS:我尝试了很多方法,最常见的方法是创建等待完成的请求设置标志的 while 循环。所有这些方法都会使浏览器认为脚本崩溃并提示用户停止脚本。

【问题讨论】:

  • 你有没有尝试在上一个的成功处理函数中再次调用该函数?

标签: javascript jquery ajax asynchronous synchronization


【解决方案1】:

简单,递归调用 ajax 请求,同时跟踪计数变量:

function makeRequest(count, finalCallback){
    someAjaxCall(data, function(){
        if(count > 1){
            makeRequest(count - 1, finalCallback);
        } else {
            finalCallback && finalCallback();
        }
    });
}

finalCallback是一个可选的回调(函数),会在所有请求完成后执行。

【讨论】:

  • 这很不错!如果makeRequest应该从调用者那里收到一个回调函数,当所有N个请求都发出后执行?
  • @MatiCicero:我添加了一个可选的finally 回调,你可以这样做:-)
  • ...但我忘了finally是JS中的保留名称,已编辑。
【解决方案2】:

你可以这样做,

var i = 5;  // number of calls to you function calling ajax
recurs(i);  // call it initially

function recurs(count) {


  makeRequest(function() {
    count--;  // decrement count
    if (count > 1) {
      recurs(count)  // call function agian
    }

  });

}

【讨论】:

  • @blex.. 抱歉.. 赶时间
  • 所以,我想发出 2 个请求:recurs(2),现在实际上会触发 3 次请求。
  • @Cerbrus.. 我想我真的很着急.. 与你竞争:p
【解决方案3】:

在这里,我使用 Promise 编写了多个 Ajax 调用。该函数将同步运行。您可以从 Ajax 中获取响应的当前位置。

var ajaxs = {
    i : 0,
    callback : null,
    param : null,
    exec_fun : function (i) {
        let data_send = this.param[i];
        let url = this.url;
        this.promise = new Promise(function (res,rej) {
              $.ajax({
                        url: url,
                        method: 'POST',
                        data: data_send,
                        dataType: 'json',
                        success: function(resvalidate){
                            res(resvalidate);
                        }
                });

        });
        this.promise.then(function (resvalidate) {
            let resp = resvalidate,
                param = ajaxs.param,
                pos = ajaxs.i,
                callback_fun = ajaxs.callback_fun;
            callback_fun(resp,ajaxs.i);
            ajaxs.i++;
            if( ajaxs.param[ajaxs.i] != undefined){
                ajaxs.exec_fun(ajaxs.i);
            }
        });


    },
    each : function (url,data,inc_callback) {
        this.callback_fun = inc_callback;
        this.param = data;
        this.url = url;

        this.exec_fun(ajaxs.i);


    }
};


let url = "http://localhost/dev/test_ajax.php";
let data_param = [{data : 3},{data : 1},{data : 2}];

ajaxs.each(url,data_param, function (resp,i) {
    console.log(resp,i);

});

【讨论】:

  • 添加ajaxs对象,然后通过ajaxs.each(...);调用
猜你喜欢
  • 2019-12-11
  • 2012-02-28
  • 2013-02-03
  • 2014-10-26
  • 2011-01-08
  • 2015-10-26
  • 2011-11-28
  • 1970-01-01
  • 2013-06-11
相关资源
最近更新 更多