我有一个函数通过在列表中的每个文件上调用单个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)等等,当它们在这样的数组中时。
提前感谢任何帮助。
答案 0 :(得分:4)
$.when
没有启动任何内容,它们是在您的地图循环中启动的。 $ .when只返回一个承诺数组的承诺。
如果您想按顺序使用它们,请使用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");
});
}
答案 1 :(得分:1)
这不是$。什么时候,是吗?似乎把它们全部发射出去了 一旦
新的更新回答: 我刚刚发现,对于新版本的jQuery(> 1.8),我们可以简单地使用$.then来链接jQuery promises。在您的情况下,您可以尝试:
function deleteFiles(filePaths){
var d = jQuery.Deferred(),
for (var i=0;i<filePaths.length;i++){
d.then(deleteFile(filePath[i]));
}
d.resolve();
}
您可以在jQuery Deferred and Promise for sequential execution of synchronous and asynchronous funcitons
查看我的类似答案旧答案:
据我了解,你需要逐个处理返回的值,我认为你不需要关心执行回调的命令为 下一个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.
});
}
}