以编程方式创建jQuery承诺的链式序列

我有一个函数通过在列表中的每个文件上调用单个deleteFile(filePath)来删除列表中的文件数组filePaths(我正在使用的一些APIS不支持批量删除)。 函数deleteFile返回jQuery promise并在删除文件时解析/拒绝。

function deleteFiles(filePaths) var deferreds = $.map(fileKeys, function (val, index) { return deleteFile(filePath); }); $.when.apply($, deferreds).then(function (schemas) { console.log("DONE", this, schemas); deferred.resolve(); }, function (error) { console.log("My ajax failed"); deferred.reject(error); }); 

我得到.reject调用列表中的一些文件(我知道它们存在),所以我想我可能需要将filePaths数组变成一个链接的调用,比如一个队列(b / c这个不是什么$。什么,是吗?它似乎立刻启动它们)。 我知道如何做到这一点(如.deleteFile(path1).deletePath(path2)等等,当它们在这样的数组中时。

任何帮助都提前得到赞赏。

$.when没有启动任何东西,它们是在你的地图循环中启动的。 $ .when只返回一个promises数组的promise。

如果你想按顺序使用它们,请使用reduce:

 function deleteFiles(filePaths) { return filePaths.reduce(function(cur, next) { return cur.then(function() { return deleteFile(next); }); }, $().promise()); } 

如果您按顺序想要它们,同时还要使用相应的结果返回数组:

 function deleteFiles(filePaths) { var ret = filePaths.slice(0); return filePaths.reduce(function(cur, next, i) { return cur.then(function() { return ret[i] = deleteFile(next); }); }, $().promise()).then(function(){ return $.when.apply($, ret); }) //These don't make any sense to call in this function but sure .then(function(schemas) { console.log("DONE", this, schemas); }).fail(function(error) { console.log("My ajax failed"); }); } 

这不是$。什么,是吗? 它似乎立刻启动它们

新的更新答案:我刚刚发现,对于新版本的jQuery(> 1.8),我们可以使用$ .then链接jQuery promises。 在您的情况下,您可以尝试:

 function deleteFiles(filePaths){ var d = jQuery.Deferred(), for (var i=0;i 

您可以在jQuery Deferred和Promise中查看我的类似答案, 以便顺序执行同步和异步函数

老答案:

据我所知,你需要逐个处理返回值,我认为你不需要关心执行回调的命令,因为下一个deleteFile不依赖于前一个的结果 。 如果是这样的话,试试这个:

  function deleteFiles(filePaths){ $.each(filePaths,function(index,val){ deleteFile(val) .done(function(schema){ }) .fail(function(error){ }); }); } 

如果你需要返回延迟,写另一种方法:

 function deleteFiles(filePaths) return $.map(fileKeys, function (val,index) { return deleteFile(val); }); } $.each(deleteFiles(yourfilePaths),function(index,val){ val .done(function(schema){ }) .fail(function(error){ }); }); 

如果你确实需要链接它们,我认为你可以创建一个这样的递归函数:

 function deleteFiles(filePaths, currentIndex){ if (filePath.length < currentIndex + 1){ //Stop condition. return; } var promise = deleteFile(filePath[currentIndex]); if (promise){ promise .done(function(schema){ //do your job with returned value, decide whether to call the next path in the chain deleteFiles(filePaths,currentIndex++); }) .fail(function(error){ //I assume that you don't call the next path if the current one returns error. }); } }