用 jQuery 接一个 AJAX 呼叫

Send one AJAX call after the other with jQuery

我在循环和对象数组时发送一个 AJAX 调用时遇到问题。代码如下

    var def = true;
    $.each(urls, function(index, val) {
        var postResult = $.Deferred();
        link = 'http://myurl.com' + val.aslug + '/' + val.slug;
        $.when(def).then(function(){
                $.post('https://graph.facebook.com ', {id : link, scrape : 'true' }, function(data, textStatus, xhr) {
                }).always(function(){

                    postResult.resolve(5);
                });

         });
         def = postResult;
    });

问题是第一次和第二次都正常。但是第三次​​调用和以下调用与第二次调用相同:/我认为每个对象都没有更改为下一个对象

在这种情况下,最简单的方法是: 在 "when-then" 构造中移动变量 link 赋值。

var def = true;
$.each(urls, function(index, val) {
    var postResult = $.Deferred();

    $.when(def).then(function(){
            var link = 'http://myurl.com' + val.aslug + '/' + val.slug;
            $.post('https://graph.facebook.com ', {id : link, scrape : 'true' }, function(data, textStatus, xhr) {
            }).always(function(){

                postResult.resolve(5);
            });

     });
     def = postResult;
});

你遇到这个问题是因为 JS 的异步能力。 $.each() - 当您的 "deferred piece of code" 变为 运行 时,循环不会等待。它循环遍历您的数组并创建将要执行的任务队列。

您也可以考虑使用 $.AJAX 和选项 async:False,而不是

您的直觉是正确的 - 最大的问题是您不想在循环中创建函数。当 $.when 第二次解析时,闭包内的 link 变量将不再引用正确的值。这就是为什么你会收到一堆相同的 url.

的电话

此外,要创建一系列承诺,您将要使用如下内容:https://github.com/kriskowal/q#sequences(不确定 jQuery 承诺是否具有类似功能)

示例代码:

// not sure if this is necessary
// haven't used jQuery promises much
var result = $.when(true);

mapUrlsToPosts(urls).forEach(function(f) {
  result = result.then(f);
});

function mapUrlsToPosts(urls) {
  return urls.map(function(url) {

    // create a function that when executed will make a request to the desired url
    return post.bind(null, url);
  });
}

function post(val) {
  var link = 'http://myurl.com' + val.aslug + '/' + val.slug,
      postResult = $.Deferred(),
      params = {
        link: link,
        scrape: 'true'
      };

  $.post('https://graph.facebook.com ', params, function(data, textStatus, xhr) {
  }).always(function(){
      postResult.resolve(5);
  });

  return postResult;
}

编辑:顺便说一句,如果您不需要等待上一个请求完成再进行下一个请求,那么所有这一切都可以变得更加简单。这里的大部分复杂性来自排队请求。