Jquery 延迟的顺序执行

sequential execution of Jquery Defers

在下面的代码中,我想在while循环中顺序执行方法saveBulkUploadSinglePacket,这意味着在当前数据包完成后处理下一个数据包。如何实现。

var saveBulkUploadSinglePacket = function(){
while (packetCount<=bulkUploadPackets.length){
            $.when(saveBulkUploadSinglePacket(modelToSave)).done(function(arguments){
                saveBulkUploadPackets.push(arguments);
                packetCount++;
            });

        }
  return saveBulkUploadPackets;

}



var saveBulkUploadSinglePacket = function(modelToSave){
        var defer = $.Deferred();
        $.when(new SaveBulkUpload().save(modelToSave)).done(function(arguments){
            defer.resolve(arguments);
        }).fail(function(errorObj){  
           defer.reject(errorObj);
        });

        return defer.promise();

    }

表达"perform x when promise is done"的标准方式是通过promise.then()。在循环外的 var 中跟踪当前的承诺,并使用 .then():

将每个调用附加到先前的承诺
var saveBulkUploadSinglePacket = function(){
    var lastPromise = $.when();
    while (packetCount<=bulkUploadPackets.length){
        lastPromise = (
           lastPromise
             .then(function(){
                 // make sure saveBulkUploadSinglePacket returns a promise
                 return saveBulkUploadSinglePacket(modelToSave));
             })
             .then(function(){
                 saveBulkUploadPackets.push(arguments);
                 packetCount++;
                 // return a resolved promise
                 return $.when();
             })
        );
    }
    lastPromise.resolve(saveBulkUploadPackets);
    return lastPromise;
}

在函数结束时,我用所需的 return 值解决了最终承诺,然后 return 编辑了承诺。这样你就可以调用 saveBulUploadSinglePacket().then(...) 等待所有的承诺完成并处理结果。

要顺序保存你的数据包,使用Array.prototype.reduce()非常简洁地构建一个.then()链,如下:

var saveBulkUploadPackets = function(packets) {
    return packets.reduce(function(promise, paket) {
        return promise.then(function(results) {
            return (new SaveBulkUpload()).save(paket).then(function(res) {
                return results.concat(res);
            });
        });
    }, $.when([]));
}

然后这样调用:

saveBulkUploadPackets(bulkUploadPackets).then(function(results) {
    // All done.
    // use/log the `results` array here.
});