当延迟 Ajax 请求完成时,Jquery Each 循环一个又一个

Chr*_*eau 2 ajax jquery

我无法解决这个问题,并且我发现了很多类似的例子,但似乎没有什么真正有效或适用于我的情况。

我的代码如下

$.each(versions, function(key,value) {
    progressText.html("Downloading Version " + value);
    ajaxUpdate('download',value).then(console.log(value));
});

function ajaxUpdate(step,value) {
    return $.ajax({
        url: 'action/' + step + '.update/',
        data: 'version=' + value
    })
}
Run Code Online (Sandbox Code Playgroud)

基本上我的问题是它each同时进行,我希望它完成一个,然后继续下一个。

我该怎么办呢?

t1m*_*m0n 5

可以使用jQuery.Deferred()object来一一发出ajax请求。如果你想在所有请求完成后调用某个函数,请使用deffer.then(...)aftereach循环:

function ajaxUpdate(step,value) {
    return $.ajax({
        url: 'action/' + step + '.update/',
        data: 'version=' + value
    })
}

// Emulate resolved deferred to be able to chain to it in each loop
var defer = $.Deferred().resolve();

$.each(versions, function(key, value) {
  // Add next deferred to chain, it will be invoked when previous is completed
  defer = defer.then(function(){
    return ajaxUpdate('download', value)
  });
});

defer.then(function(){
    console.log('All requests completed')
})
Run Code Online (Sandbox Code Playgroud)

超时示例

function ajaxUpdate(step,value) {
    return $.ajax({
        url: 'action/' + step + '.update/',
        data: 'version=' + value
    })
}

// Emulate resolved deferred to be able to chain to it in each loop
var defer = $.Deferred().resolve();

$.each(versions, function(key, value) {
  // Add next deferred to chain, it will be invoked when previous is completed
  defer = defer.then(function(){
    return ajaxUpdate('download', value)
  });
});

defer.then(function(){
    console.log('All requests completed')
})
Run Code Online (Sandbox Code Playgroud)
var $log = $('#log');

function ajaxUpdate(url, step) {
  return $.Deferred(function() {

    setTimeout(function() {
      $log.append('<p>finished:' + step + '</p>')
      this.resolve();
    }.bind(this), Math.random() * 1000)

  })
}

var defer = $.Deferred().resolve();
var versions = [1, 2, 3, 4, 5];

$.each(versions, function(key, value) {
  defer = defer.then(function() {
    return ajaxUpdate('download', value)
  });
});

defer.then(function() {
  $log.append('<p>All Done</p>')
});
Run Code Online (Sandbox Code Playgroud)