当多个asyc调用完成时,AJAX启动最终的asyc调用

时间:2015-11-12 14:28:47

标签: javascript ajax

我正在考虑如何更好地管理运行多个异步调用的顺序,以实现最佳的周转时间。基本上这个过程是这样的: 当网页开始加载时,它会显示页面并启动几个AJAX调用a(),b()和c()。完成这三个后,运行异步调用d()。我检查了几个线程,如jquery execute function when two conditions are met,但这并不完全相同。

我尝试使用多个标志来显示异步调用是否完成以及一个阻止该过程的阻止功能,直到它可以拍摄最后一个呼叫。

var aFinished=false;
function a() {
      var jsonData = $.ajax({
        url: "${createLink(controller:'environment', action:'a')}",
        dataType: "json",
        async: true
      }).done(function(jsonData) {
          //do something
          aFinished=true;
    });
}
//same flag+function for b() and c()
function d(){
    blockTillAllDone();
    var jsonData=$.ajax(...).done(...);
}
function blockTillAllDone(){
    if(aFinished&&bFinished&&cFinished){
        console.log("Ok to continue");
        return;
    }
    else{
        console.log("Have to wait");
        setTimeout(blockTillAllDone(),2000);
    }
}
a();b();c();d();

由于递归块功能导致堆栈不断增长,性能并不是很好。有没有人有更好的想法如何以更多的AJAX方式实现这一点,而不是一个暴力块功能? 提前谢谢!

3 个答案:

答案 0 :(得分:2)

您正在寻找promises

This article在解释基础知识方面做得很好。虽然许多浏览器现在都在本地支持它们(除IE之外),但您仍然希望包含像es-6 promise这样的polyfill。一旦你开始使用promises,你就可以解决你的问题:

var a = new Promise(function(resolve,reject){
    $.ajax({
        type: 'GET',
        dataType: 'json',
        url: 'example.com/test/1',
        success: function(response){resolve(response);},
        error: function(response){reject(response);}
    });
});

var b = new Promise(function(resolve,reject){
    $.ajax({
        type: 'GET',
        dataType: 'json',
        url: 'example.com/test/1',
        success: function(response){resolve(response);},
        error: function(response){reject(response);}
    });
});

var c = new Promise(function(resolve,reject){
    $.ajax({
        type: 'GET',
        dataType: 'json',
        url: 'example.com/test/1',
        success: function(response){resolve(response);},
        error: function(response){reject(response);}
    });
});

//This will run once all async operations have successfully finished
Promise.all([a,b,c]).then(
    function(data){
        //everything successful, handle data here
        displayData(data);
    },
    function(data){
        //something failed, handle error here
        logoutError(data);
    }
);

答案 1 :(得分:1)

您可以尝试基于事件的方法。将方法a()b()c()放在一个类中,如果完成了所有三个检查,则完成每个检查,如果完成,则引发一个将由监听器捕获的事件然后它可以执行d()

我将尝试使用代码演示此内容。

答案 2 :(得分:1)

将支票移入d()并调用done(..)(除非您希望它发生,无论是否成功 - 在这种情况下使用always(..))a,b和c

var aFinished=false;
function a() {
      var jsonData = $.ajax({
        url: "${createLink(controller:'environment', action:'a')}",
        dataType: "json",
        async: true
      }).done(function(jsonData) {
          //do something
          aFinished=true;
          d();
      });
}
//same flag+function for b() and c()
function d(){
    if(aFinished&&bFinished&&cFinished){
        var jsonData=$.ajax(...).done(...);
    }
}

a();b();c();

然后您无需blockTillAllDonesetTimeout