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

时间:2013-02-21 14:04:53

标签: jquery jquery-deferred

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

Item:
ItemId

Images:
ImageId
ItemId

所以必须先删除图像,然后才能删除与其关联的项目,否则我的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();
}

似乎大部分时间都是以预定的顺序进行呼叫,但并非始终如此。帮我找到一个小细节,我确定我不知道。

1 个答案:

答案 0 :(得分:1)

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

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');
         });
}