在循环中使用JQuery Ajax延迟

时间:2013-10-26 21:44:16

标签: jquery ajax loops deferred

我需要通过REST将大量项目传递给API。我需要遍历一组项目并将每个项目激活到远程API。目的是在每次调用API之间等待成功

这是我目前尝试使用JQuery的承诺:

items.each(function(model) {
    $.when(addItem(model,endpoint)).done(function(data, xhr, results) {
        console.log('added');
  });

Ajax调用如下所示:

  addItem: function(model, endpoint) {
    return $.ajax({
      url: 'http://api' + endpoint,
      type: "POST",
      headers: {
        "accept":"application/json"
      },
      dataType: "json",
      data: {
        item: model.attributes.id,
        amount: model.attributes.amount
      }
    });
  }
};

当代码在循环中运行多次时,我得到一些项目被存储,一些回复500响应,一些回复409(重复)响应。我可以手动将项目添加到API而不会出现问题。可能只是循环对API的运行速度太快,但它可能是我的代码。我知道有更好的方法来添加项目,但目前我必须使用这个循环的想法进行测试,直到将来的API代码迭代。

上述内容是否正确,还是有更好的解决方法?

2 个答案:

答案 0 :(得分:0)

你可以通过在AJAX调用成功时递归调用它们来链接你的AJAX调用,或者你可以使调用同步(通过使用async: false):

$.ajax({
    url: 'http://api' + endpoint,
    type: "POST",
    async: false, 
    headers: {
      "accept":"application/json"
    },
    dataType: "json",
    data: {
      item: model.attributes.id,
      amount: model.attributes.amount
    }
});

请注意,使其同步将阻止任何其他Javascript运行,因为Javascript是单线程的。

答案 1 :(得分:0)

您应该能够按顺序附加回调,并在Deferred回调中小心使用递归。这是一种可能的实现方式:

// I'm paranoid about making sure basic prototype functions are available
// even if some library clobbers the original definition later.
var slice = Array.prototype.slice;

// This function should be `.apply`'d with the array of models you need to add.
// It will call `addItem` on the first argument, and then use this function as
// a callback to `addItem` with the arguments shifted by one.
var invokeAddItem = function (modelToAdd) {
    var rest = slice.call(arguments, 1);

    addItem(modelToAdd, endpoint).always(function () {
        invokeAddItem.apply(null, rest);
    });
};

invokeAddItem.apply(null, items);    // Equivalent to `invokeAddItem(items[0], ...)`