【问题标题】:sequential execution of Jquery DefersJquery Defers 的顺序执行
【发布时间】:2016-04-13 19:20:57
【问题描述】:

在下面的代码中,我希望在 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();

    }

【问题讨论】:

    标签: javascript jquery jquery-deferred


    【解决方案1】:

    说“当承诺完成时执行 x”的标准方式是通过 promise.then()。在循环外的 var 中跟踪当前的 Promise,并使用 .then() 将每个调用附加到上一个 Promise:

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

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

    【讨论】:

    • 它在抱怨 lastPromise.resolve 不是一个函数。
    • 忘记在lastPromise var中保存顺序承诺;尝试更新的代码
    • 再看一遍,我认为问题可能是你的函数被传递给.then()saveBulkUploadSinglePacket()saveBulUploadPackets() 周围的匿名函数)没有返回承诺,所以@ 987654329@s 没有正确链接。我更新了第二个函数中的代码以手动创建并返回一个 Promise,但您需要确保 saveBulkUploadSinglePacket() 在完成时也返回一个 Promise
    • $.when() 并不是要采用异步函数并将其转换为基于承诺的函数,而是要与同步函数一起使用。所以我有两个关于SaveBulkUpload.save()的问题:第一,它是异步的吗?例如,是否使用 AJAX 向服务器发送数据?如果它 不是 异步的,那么问题就出在其他地方。如果它,第二个问题:它是否返回一个promise?如果没有,$.when() 对你没有任何好处;它不会等待save() 完成。如果是这样,这个功能是不必要的。只需直接从while 循环中调用(new SaveBulkUpload().save(modelToSave))
    • 如果它实际上是在返回一个承诺,那么如果不坐在整个代码库前四处寻找,我真的没有什么可以告诉你的了。如果您仍然收到 lastPromise.resolve() 不是函数的错误,并且您确定您的代码与我上面的代码匹配,我会在该行之前尝试 console.log(lastPromise) 以确保您真的得到你认为你得到了什么。尝试在整个函数中添加控制台日志;你可能会发现一些惊喜
    【解决方案2】:

    为了顺序保存你的包,使用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.
    });
    

    【讨论】:

      猜你喜欢
      • 2011-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-16
      • 2016-12-01
      • 1970-01-01
      相关资源
      最近更新 更多