【问题标题】:Run two functions with Ajax calls sequentially使用 Ajax 调用顺序运行两个函数
【发布时间】:2015-10-25 17:08:27
【问题描述】:

我有两个函数,其中包含ajax calls

function a(){
    ajaxCall_A();
}
function b(){
    ajaxCall_B();
}

我还有另一个函数,它按照a 然后b 的顺序调用这两个函数。

function c(){
    a();
    b();
    // expectation : function 'b' will get executed only after function 'a' finished it's execution  
}

我不确定它们是否按预期工作。有时会,但有时不会。我认为这是因为它们内部的 ajax 调用是异步的。

如何运行函数“c”中的两个函数以达到预期。

注意:功能如下

function a(){ 
    $.ajax({
        url: "url_a",
        type: "post",
        dataType: "html",               
        cache: false,
        success: function(data){             

        },
        error:function(){             

        }   
    });   
}

function b(){ 
    $.ajax({
        url: "url_b",
        type: "post",
        dataType: "html",               
        cache: false,
        success: function(data){             

        },
        error:function(){             

        }   
    });   
}

【问题讨论】:

  • 您的上一次修订毫无意义。 ajaxCall_A 不是函数调用。它实际上并没有做任何事情。你需要 () 在它之后使它成为 ajaxCall_A() 中的函数调用,或者你需要向我们展示实际的 ajax 代码。
  • 如果您需要更详细的帮助,请不要只显示伪代码,而是向我们展示实际的 Ajax 代码。
  • @jfriend00 已编辑。对不起这个错误。
  • 如果投反对票的人能给出一个理由就更好了。将有助于改进。

标签: javascript jquery ajax


【解决方案1】:

由于 ajax 调用是异步的,如果您希望在第一个调用完成之前不启动第二个调用,则需要手动排序 ajax 调用。

Promises 非常适合序列化异步操作,它们可以让它变得非常简单。幸运的是,jQuery 内置了 Promise,并且每个 Ajax 操作都已经返回了一个可以用于此目的的 Promise:

$.ajax(...).then(function(result1) {
    // make 2nd ajax call when the first has completed
    return $.ajax(...);
}).then(function(result2) {
    // success of both ajax calls here
}, function(err) {
    // error here
});

或者,如果你让 a()b() 都从它们的 ajax 调用中返回 jQuery ajax 承诺,那么你可以这样做:

a().then(b);

而且,c() 可能只是:

function c() {
    return a().then(b);
}

因此,如果您想在没有a()b() 的情况下进行函数调用以包含这两个Ajax 调用,您应该让它返回一个promise:

function c() {
    return $.ajax(...).then(function(result1) {
        // make 2nd ajax call when the first has completed
        return $.ajax(...);
    })
}

然后,您可以像这样调用c()

c().then(function(result) {
    // success here
}, function(err) {
    // error here
});

这是一个返回 Ajax 承诺的函数示例:

function test() {
    return $.ajax("http://www.test.com/api/test");
}

现在,您已经添加了实际的 ajax 代码,您只需添加一个 return:

function a(){ 
    return $.ajax({
        url: "url_a",
        type: "post",
        dataType: "html",               
        cache: false
    });   
}

function b(){ 
    return $.ajax({
        url: "url_b",
        type: "post",
        dataType: "html",               
        cache: false
    });   
}

function c() {
    return a().then(b);
}

【讨论】:

  • @prime - 目前尚不清楚您的更新有何变化。在您的问题下方查看我的 cmets。
  • 请参考问题。我刚刚更新并添加了功能的实际外观。我希望没关系。那么在ajax调用之前添加return可以吗?
  • @prime - 是的,您可以添加return。看看我在答案末尾添加了什么。
  • 所以可以像return a().then(b).then(d); if I have multiple functions
  • @prime - 是的。只需确保所有包含异步操作的函数都返回一个与异步操作相关的承诺,并且您可以像这样链接任意数量。
【解决方案2】:

确保ajaxCall_A()ajaxCall_B() 返回承诺,并将returns 添加到a()b()

function a(){
    return ajaxCall_A();
}
function b(){
    return ajaxCall_B();
}

然后,a()b() 将按如下顺序执行:

function c() {
    a().then(b);
}

您还应该将return 添加到c(),以便它向调用者返回一个承诺。

function c() {
    return a().then(b);
}

【讨论】:

  • Make sure that ajaxCall_A() and ajaxCall_B() return promises 我该怎么做?
  • 在这两个函数中,return $.ajax({...});
【解决方案3】:

只需将 jQuery.when() 和 done() 与 Deferred 一起使用:

    function a() {
        var deferred = $.Deferred();

        $.ajax({
        url: "url_a",
        type: "post",
        dataType: "html",               
        cache: false,
        success: function(data){             
            deferred.resolve(data);
        },
        error:function(){             
           deferred.resolve("Error from a()");
       }   
      });  
      return deferred.promise();
    }
    function b() {
        var deferred = $.Deferred();

        $.ajax({
        url: "url_b",
        type: "post",
        dataType: "html",               
        cache: false,
        success: function(data){             
            deferred.resolve(data);
        },
        error:function(){             
           deferred.resolve("Error from b()");
       }   
      }); 

        return deferred.promise();
    }

    function c()
    {
        $.when(
            a(),
            b()
       )
      .done(function ( v1, v2 ){
      //Do your work - v1 and v2 are resolved value from a() and b() 
      });       
    }

【讨论】:

    【解决方案4】:

    允许a函数接受一个回调参数,完成后执行,并发送b函数作为回调:

    function c(){
      a(b); 
    }
    
    function a(callback){ 
      $.ajax({
        url: "url_a",
        type: "post",
        dataType: "html",               
        cache: false,
        success: function(data){             
          callback() // Note here call the next function
        },
        error:function(){             
    
        }   
      });   
    }
    

    【讨论】:

      【解决方案5】:

      您需要使用信号量来同步它们

      function c(){
          $semaphore=true;
          a();
          while($semaphore ) { 
               setTimeout("checksemaphore()", 500);
          } 
          b();
          // expectation : function 'b' will get executed only after function 'a' finished it's execution  
      }
      
      
      inside the ajax call to a
      add a complete: 
      
      complete : function(result) { 
                  $waitsemaphore= 0 ; },
      error: function(result) {alert("AJAX completed w/error");alert(result);},
      

      【讨论】:

      • 当您可以直接挂钩到完成事件本身或承诺通知时,为什么还要轮询完成?这里根本不需要setTimeout() 投票。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-24
      • 2019-08-30
      • 1970-01-01
      • 2021-02-28
      • 2019-04-13
      • 1970-01-01
      相关资源
      最近更新 更多