如何使用 jQuery Promise链接三个异步调用?

IT技术 javascript jquery asynchronous deferred
2021-02-06 21:32:19

我需要以同步方式进行三个 HTTP 调用,如何将数据从一个调用传递到另一个调用?

function first()
{
   ajax()
}

function second()
{
   ajax()
}

function third()
{
   ajax()
}


function main()
{
    first().then(second).then(third)
}

我尝试将 deferred 用于这两个函数,并提出了部分解决方案。我可以将其扩展为三个功能吗?

function first() {
    var deferred = $.Deferred();
     $.ajax({

             "success": function (resp)
             {

                 deferred.resolve(resp);
             },

         });
    return deferred.promise();
}

function second(foo) {
     $.ajax({
            "success": function (resp)
            {
            },
            "error": function (resp)
            {
            }
        });
}


first().then(function(foo){second(foo)})
6个回答

在每种情况下,返回由 返回的 jqXHR 对象$.ajax()

这些对象是无极兼容,以便在与被链接.then()/ .done()/ .fail()/ .always()

.then() 在这种情况下是你想要的,就像问题中一样。

function first() {
   return $.ajax(...);
}

function second(data, textStatus, jqXHR) {
   return $.ajax(...);
}

function third(data, textStatus, jqXHR) {
   return $.ajax(...);
}

function main() {
    first().then(second).then(third);
}

参数data,textStatusjqXHR产生$.ajax()于前一个函数中调用,即。first()饲料second()second()饲料third()

DEMO$.when('foo')用于交付已履行的Promise,代替$.ajax(...))。

这对我不起作用。当我尝试你的例子时,第一个的结果被传递给第二个和第三个。所以第一个喂第二个和第三个。不是第一个喂第二个,第二个喂第三个。$.ajax({...}).then(function(..){ return $.ajax({...}); }).then( function(...){ /* 我想要结果第二次调用。*/ });
2021-03-18 21:32:19
不幸的是,我无法用小提琴(使用 gmaps)重新创建我的代码,但是当我尝试像这样简单的事情时:jsfiddle.net/CbPbw/1它按预期工作。我必须找出我的代码有什么问题。谢谢
2021-03-18 21:32:19
现在没有时间运行测试,但我不明白为什么我的答案中的代码不起作用。确保您使用的是 jQuery 1.8.3 或更高版本。早期版本很可能会给出您描述的症状。
2021-03-27 21:32:19
@pajics,我在答案中添加了一个演示。要么 1.11.0 已恢复,要么您做错了什么。你能提供一个小提琴吗?
2021-03-27 21:32:19
刚刚检查了 jquery 1.11.0 并且所有 then 调用从 when 而不是从以前的 then 获取参数。
2021-04-08 21:32:19

在 jQuery 中使用 Promise 时,实际上有一种更简单的方法。看看以下内容:

$.when(
    $.ajax("/first/call"),
    $.ajax("/second/call"),
    $.ajax("/third/call")
    )
    .done(function(first_call, second_call, third_call){
        //do something
    })
    .fail(function(){
        //handle errors
    });

只需将所有调用链接到 $.when(...) 调用中并处理 .done(...) 调用中的返回值。

如果您愿意,这里有一个演练:http : //collaboradev.com/2014/01/27/understanding-javascript-promises-in-jquery/

本例中的三个 ajax 调用将异步发生
2021-03-13 21:32:19
此答案不会链接请求,而是并行运行。
2021-03-27 21:32:19
@Emilio,没错。这就是 OP 所要求的,而这个答案在这方面并没有提供。
2021-04-01 21:32:19
回答一个完全不同的问题。建议删除以避免混淆。
2021-04-01 21:32:19
不是 OP 正在寻找的答案,而是我所寻找的答案。谢谢!
2021-04-10 21:32:19

回复很晚,但我想答案缺少一些用于链接的直接代码。使用 jquery 中的 promise 支持链接事件非常简单。我使用以下链接:

$.ajax()
.then(function(){
   return $.ajax() //second ajax call
})
.then(function(){
   return $.ajax() //third ajax call
})
.done(function(resp){
   //handle final response here
 })

它很简单,没有复杂的 for 循环或多个嵌套回调。

它比那简单得多。

$.ajax 已经返回一个Promise(延迟对象),所以你可以简单地写

function first() {
    return $.ajax(...);
}
@SLaks 当时是否有可能推迟不止一个?first().then(second, third).then(fourth);?
2021-03-11 21:32:19
如何链接多个 ajax 调用并传递返回值?deferred.resolve 曾经是我过去的做法。
2021-03-13 21:32:19
@SLaks - 请扩展您的答案以更好地解释所问的问题,因为您的答案似乎对 jQuery ajax 对象的性质和基础非常重要,因此值得多写几行来解​​释如何链接多个异步函数
2021-03-19 21:32:19
@JohnMcdock:从.then()(在 1.8+ 中)返回一个值api.jquery.com/deferred.then
2021-04-08 21:32:19

您可以以更实用的方式编写它:

[function() { return ajax(...)}, function(data) { return ajax(...)}]
.reduce(function(chain, callback) { 
  if(chain) { 
    return chain.then(function(data) { return callback(data); });
  } else {
    return callback();
  }
}, null)