【问题标题】:Multiple jQuery promises in sequential order多个 jQuery 承诺按顺序排列
【发布时间】:2015-09-26 01:00:39
【问题描述】:

基本上我想要这个:

function do_ajax_calls(...){
  var d = $.Deferred();

  $.ajax(args).done(function(){

    $.ajax(args).done(function(){

      $.ajax(args).done(function(){
         d.resolve();
      });

    });

  })

  return d.promise();
}

但是ajax调用的数量取决于我传递给函数的参数,这是一个数组,所以我不能使用那个代码。

该函数应该返回一个仅在最后一个 ajax 调用完成时才解析的 Promise。所以函数需要这样调用:

 do_ajax_calls(....).done(function(){
   // here is the callback
 })

有人知道我该怎么做吗?

【问题讨论】:

  • 我认为通过某种 eval 我可以传递之前构建的字符串,但我不确定这是否是最好的方法

标签: javascript jquery promise jquery-deferred


【解决方案1】:

但是ajax调用的数量取决于我传递给函数的参数,它是一个数组

如果是每个数组项一个 ajax 调用

function do_ajax_calls(args) {
    return args.reduce(function(promise, item) {
        return promise.then(function() { 
            return $.ajax(args); // should that be item?
        });
    }, Promise.resolve(true));
}

Promise.resolve(true) 是一个“原生”承诺,即在 IE 中不可用,但我确信 jQuery 有一个等价物

这是一个JSFiddle 演示

【讨论】:

    【解决方案2】:

    promise 之所以重要的原因之一是因为它们可以被链接起来。您可以利用这一点将其他请求迭代地链接到前一个请求的解决方案上:

    function do_ajax_calls() {
        var dfd = $.Deferred();
        var promise = dfd.promise();
        var responses = [];
    
        function chainRequest(url) {
            promise = promise.then(function (response) {
                responses.push(response);
                return $.ajax(url, { method: 'POST' });
            });
        }
    
        for (var i = 0, length = arguments.length; i < length; i++) {
            chainRequest(arguments[i]);
        }
    
        dfd.resolve();
    
        return promise.then(function (response) {
            return responses.slice(1).concat(response);
        });
    }
    

    上面的代码将返回一个最终解析为所有响应数组的承诺。如果任何一个请求失败,promise 将在第一次失败时拒绝。

    JSFiddle

    【讨论】:

    • 看起来这行不通。循环中的那些 ajax 调用都立即触发?
    • 抱歉我很挑剔,但我认为这也行不通,因为 url 变量在内部函数中。我认为这将是未定义的。我知道是因为我遇到过这个问题
    • 您说得有道理,但并不是说该变量是未定义的。我在这里有一个愚蠢的竞争条件,我在小提琴中看不到,因为我每次都发送相同的 URL。我又修好了。
    【解决方案3】:

    这是Demo

    var counter = 1 ;
    
    function multipleAjax(loop)
    {
       if(counter<loop)
       {
            $.ajax(
            {
                url: 'http://mouadhhsoumi.tk/echo.php',
                success:function(data)
                {
                    multipleAjax(loop);
                    $(".yo").append(data+"</br>");
                    counter++;
                }
            });
    
       }
    }
    multipleAjax(5);
    

    【讨论】:

    • 这个答案违背了承诺的意义,即链接和可组合性。这与使用纯回调没有什么不同。
    【解决方案4】:

    尝试使用$.when()Function.prototype.apply()$.map()

    function do_ajax_calls(args) {
      return $.when.apply($, $.map(args, function(request, i) {
        return $.ajax(request) // `request` : item with `args` array
      }))
    }
    
    do_ajax_calls
    .then(function success() {
      console.log(arguments)
    }, function err() {
      console.log("err", arguments)
    });
    

    【讨论】:

      猜你喜欢
      • 2016-10-28
      • 2019-06-16
      • 2019-05-30
      • 2020-06-16
      • 1970-01-01
      • 2013-12-04
      • 2018-09-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多