【问题标题】:Converting a series of synchronous AJAX requests to asynchronous requests将一系列同步的AJAX请求转换为异步请求
【发布时间】:2013-03-09 08:38:00
【问题描述】:

如何在下面的函数中发出第二个 AJAX 请求异步而不是同步? result 是一个字符串,它应该以 'start of string' 开头并以 'end of string' 结尾,但在字符串的中间将是正在迭代的初始 AJAX 请求的结果。

Foo = {
    foo: function() {
        $(document).on("change", '.foo', function(e) {
            e.preventDefault();
            $.ajax({
                url: "foo.php",
                success: function(rows) {
                    $.each(rows, function() {
                        var result = 'start of string'; // START
                        $.ajax({
                            url: "bar",
                            async: false, // I DON'T want this
                            success: function(data) {
                                result += data; // MIDDLE
                            }
                        });
                        result += 'end of string'; // END
                    });
                }
            });
        });
    }
}

谢谢。

【问题讨论】:

    标签: ajax jquery


    【解决方案1】:

    您可以利用 jquery 延迟对象。您可以在不同的函数中有两个不同的 ajax 调用,然后您可以使用 .done() 方法确保在两个 ajax 调用都完成后获得最终字符串。

    在这里阅读更多:

    【讨论】:

      【解决方案2】:

      最简单的方法确实是使用延迟对象,例如使用 jQuery whendone 延迟语句的 JavaScript 示例;

      $.when(ajaxCallOne()).done(ajaxCallTwo(rows));
      
      function ajaxCallOne() {
          return $.ajax({
                      url : "foo.php",
                      async: true
                  });
      }
      
      function ajaxCallTwo(rows) {
          var result = 'start of string';
          $.each(rows, function() {
              $.ajax({
                  url : "bar",
                  async : true,
                  success : function(data) {
                      result += data; // MIDDLE
                  }
              });
              result += 'end of string'; // END
          });
      
          return result;
      }
      

      我不是 JavaScript 或 jQuery 专家,但我认为你应该看看那些延迟对象。

      【讨论】:

      • 请注意,ajaxCallTwo 将同时触发所有 ajax 请求,而不是按顺序触发
      • @Manolo,是吗? when.done 将在调用一终止后执行 callTwo 对吗?这是 Tharwat 的帖子中描述的 Promise 设计模式。
      【解决方案3】:

      我觉得你应该看看javascript promise design pattern

      让我向你解释一下:

      这个承诺是一种代理,代表未来的结果 手术。然后,您将在 Promise 上注册一个回调,该回调 操作完成后将由 Promise 执行,并且 结果是可用的。

      使用 jQuery,您可以像这样定义 Promise:

      var promise = $.getJSON('url');
      

      然后使用您的 promise 变量,您可以定义当您的请求完成或失败时要做什么,甚至可以在请求失败或成功时执行某些功能。

      promise.done(function(s) {alert('done successfully'); });
      promise.fail(function(){ alert('get failed!'); });
      promise.always(function(){ alert('this 'll executed anyway!'); });
      

      上面有很多教程

      Promises and Deferred objects in jQuery

      jQuery: Deferred Object

      javascript promises

      What is the benefit of a 'promise' abstraction in CommonJS?

      【讨论】:

        【解决方案4】:

        在 jquery 中链接异步调用的方法是使用promise.then(),在以前的 jquery 版本中也称为promise.pipe()

        Foo = {
            foo: function() {
                $(document).on("change", '.foo', function(e) {
                    e.preventDefault();
        
                    var param1 = {url: "foo.php"};
                    var param1 = {url: "bar"};
        
                    $.ajax(param1)
                       .then(function(rows) {
                            var result = 'start of string'; //START
                            var fn = function(data) {
                               result += data;
                            }
                            var last, first;
                            $.each(rows, function() { // rows should be iterable
                                if (!last) { 
                                   first = last = $.ajax(param2).done(fn)
                                } else {
                                   last = last.then(function(res) {
                                      return $.ajax(param2).done(fn);
                                   });
                                }
                            });
                            last.done(fn).done(function() {
                               result += 'end of string'; // END
                            });
                            return first;
                       });
                });
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-04-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-08-19
          • 2016-10-22
          相关资源
          最近更新 更多