0

我需要通过 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 代码的未来迭代。

以上看起来是否正确,还是有更好的方法来解决这个问题?

4

2 回答 2

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 是单线程的。

于 2013-10-26T22:20:13.267 回答
0

您应该能够通过在延迟回调中仔细使用递归来按顺序附加回调。这是一种可能的实现:

// 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], ...)`
于 2013-10-26T22:27:46.280 回答