多个AJAX调用没有阻塞

时间:2017-01-25 10:32:20

标签: javascript jquery ajax

我每60秒运行一个名为checker的函数,如下所示:

setInterval( checker, 60 * 1000 );

checker有一个通过AJAX检查的URL数组,当前代码是这样的:

$.ajax({
  url: sites[i].url,
  type: "GET",
  dataType: "json",
  async: false,
  success: function(data){
     //blah blah blah
  }else{
     //something else
  },
  error: function(){
    //blah blah blah
  }
});

代码可以运行,根据JSON的结果更改一些基于UI的东西。我的问题是这个检查几个站点的执行时间是~4秒,此时页面变得没有响应。如果我删除async: false,则代码将无法按预期运行。

有人提到使用回调来解决问题但不了解如何在这种情况下使用它们。

修改

根据adosan的建议更新了代码:

function promtest(){
    var sites = [
             { name: "WorkingSite", url: "http://sitename.com/testing.php" },
             //a bunch more sites, 1 returns a 404 to test for failure
             { name: "404Site", url: "http://404url.com/testing.php" }
             ];

    var promiseList = [];
    for(var i in sites){
    var promise = $.ajax({
    url: sites[i].url,
    type: "GET",
    dataType: "json",
    async: true,
    success: function(data){

      if( data.Response != 'OK' ){
        console.log('Site ' + sites[i].name + ' Not OK' );
      }else{
        console.log( 'Site ' + sites[i].name + ' OK ');
      }
    },

    failure: function(data){
      console.log('Failure for site: ' + sites[i].name);
    },

    error: function(){
      console.log('Site ' + sites[i].name + ' Not OK' );
    }

    });

    promiseList.push(promise);
    }

    $.when.apply($, promiseList).then(function(){console.log('success')}, function(){console.log('fail')});

}

在控制台中我看到:

Site 404Site Not OK
Site 404Site Not OK
Site 404Site Not OK
Site 404Site Not OK
Site 404Site Not OK
Site 404Site Not OK
Site 404Site Not OK
fail
Site 404Site Not OK
Site 404Site Not OK
Site 404Site Not OK
Site 404Site Not OK

请注意,网站名称始终显示为列表中的最后一个。

3 个答案:

答案 0 :(得分:2)

您可以在此处使用Promise(https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise)。例如:

function checker(url) {
    return new window.Promise(function (resolve, reject) {

        function successCallback(response) {
            resolve(response);
        }

        function errorCallback(response) {
            reject(response);
        }

        $.ajax({
            data: data,
            dataType: 'JSON',
            type: 'GET',
            url: url
        })
        .done(successCallback)
        .fail(errorCallback);
    });
}

function checkerSuccess(response) {
    console.log(response);
}

function checkerError(error) {
    console.warn(error);
}

checker('http://api.example.com').then(checkerSuccess).catch(checkerError);

答案 1 :(得分:1)

您可以使用jQuery内置的延迟机制(一个承诺)。

https://api.jquery.com/category/deferred-object/

jQuery.ajax 函数确实返回一个可以作为变量赋值的promise对象。

https://api.jquery.com/jQuery.ajax/

 var promise = $.ajax({
      url: sites[i].url,
      type: "GET",
      dataType: "json",
      async: true
    });

承诺的好处在于你可以将多个承诺组合成更大的承诺。

var promiseList = [];
promiseList.push(promise);
$.when.apply($, promiseList).then(function(){/*SUCCESS*/}, function(){/*FAILURE*/});

完整代码应如下所示:

var promiseList = [];
for(var i in sites){
    var promise = $.ajax({
      url: sites[i].url,
      type: "GET",
      dataType: "json",
      async: true
    });

    promiseList.push(promise);
}
$.when.apply($, promiseList).then(function(){/*SUCCESS*/}, function(){/*FAILURE*/});

答案 2 :(得分:0)

我会尝试这个。

让我们说你想要更新的对象是var foo:

var foo = "";

$.ajax({
      url: sites[i].url,
      type: "GET",
      dataType: "json",
      async: false,
      success: function(data){

          foo = data.gottenValue1

      }else{
         //something else
      },
      error: function(){
        //blah blah blah
      }
    });