我的jQuery Deferred()用法有什么问题



我正在尝试使用Deferred来正确地排序对API的删除调用。该应用程序处理项目和图像:

Item:
ItemId
Images:
ImageId
ItemId

因此,必须先删除图像,然后才能删除与其关联的Item,否则我的DeleteItem()ajax调用将在数据对象中返回错误。

在下面的代码中,我试图在进行任何DeleteItem()ajax调用之前,对所有DeleteImage()ajax调用进行分组。

var deferreds1 = [];  
var deferreds2 = [];   
...
// push()ing an unknown number of DeleteImage() ajax calls to deferred1 
// push()ing an unknown number of DeleteItem() ajax calls to deferred2
...
if (deferreds1.length > 0) {
    $.when
        .apply($, deferreds1)
        .then(function(){
             console.log('deferred1 then');
             $.when
                  .apply($, deferreds2)
                  .then(function() {
                       console.log('deferred2 then');
                  })
                  .fail(function() {
                       console.log('deferred2 fail');
                  });
             })
         .fail(function(){
              console.log('deferred1 fail');
         });
}
function DeleteItemImage() {
    var dfd = $.Deferred();
    $.ajax({
        ...
        success: function (data) {
            if (!data.success) {
                alert('error');
            }
            dfd.resolve();
        }
        ...
    }); 
    return dfd.promise();
}
function DeleteItem() {
    var dfd = $.Deferred();
    $.ajax({
        ...
        success: function (data) {
            if (!data.success) {
                alert('error');
            }
            dfd.resolve();
        }
        ...
    }); 
    return dfd.promise();
}

似乎大部分时间都是按照预定的顺序打电话,但并非所有时间都是这样。帮我找到一个小细节,我确信我遗漏了。

在解决所有DeleteItemImage延迟之前,您似乎正在调用DeleteItem函数。我认为你应该这样做。

var deferreds1 = [];  
var deferreds2 = [];   
...
// push()ing an unknown number of DeleteImage() ajax calls to deferred1 
// do not call DeleteItem here.  Wait until all of deferreds1 are resolved.
...
if (deferreds1.length > 0) {
    $.when
        .apply($, deferreds1)
        .done(function(){
             console.log('deferred1 done');
             // NOW call DeleteItem and add to deferreds2,
             // since now all the Images are deleted.
             deferreds2.push(DeleteItem()); // for each item...
             $.when
                  .apply($, deferreds2)
                  .done(function() {
                       console.log('deferred2 done');
                  })
                  .fail(function() {
                       console.log('deferred2 fail');
                  });
             })
         .fail(function(){
              console.log('deferred1 fail');
         });
}

最新更新