以编程方式创建jQuery承诺的链接序列
我有一个函数,可以通过对列表中的每个文件(我使用的一些API不支持批量删除)调用单个deleteFile(filePath)来删除一个列表和一个文件数组filePath。函数deleteFile返回jQuery承诺,并在删除文件时解析/拒绝以编程方式创建jQuery承诺的链接序列,jquery,asynchronous,promise,jquery-deferred,Jquery,Asynchronous,Promise,Jquery Deferred,我有一个函数,可以通过对列表中的每个文件(我使用的一些API不支持批量删除)调用单个deleteFile(filePath)来删除一个列表和一个文件数组filePath。函数deleteFile返回jQuery承诺,并在删除文件时解析/拒绝 function deleteFiles(filePaths) var deferreds = $.map(fileKeys, function (val, index) { return deleteFile(filePath);
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调用(我知道它们存在),因此我想我可能需要将文件路径数组转换为调用链,就像队列一样(b/c这不是$。什么时候做的,是吗?似乎一次启动它们)。我知道当它们在这样的数组中时如何做(比如.deleteFile(path1).deletePath(path2).etc)
任何帮助都将提前得到感谢
这不是$所说的。它什么时候做的,是吗?它似乎一下子就把它们都推出了
一次
新的更新答案:
我刚刚发现,对于jQuery(>1.8)的新版本,我们可以简单地使用链接jQuery承诺。在您的情况下,您可以尝试:
function deleteFiles(filePaths){
var d = jQuery.Deferred(),
for (var i=0;i<filePaths.length;i++){
d.then(deleteFile(filePath[i]));
}
d.resolve();
}
如果您需要返回延期付款,另一种写此内容的方法:
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.
});
}
}
函数删除文件(文件路径、当前索引){
如果(filePath.length
$。当
没有启动任何东西时,它们会在地图循环中启动。$。当只返回一个承诺数组的承诺时
如果要按顺序执行,请使用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");
});
}
即使其中一个ajax请求失败,那么$。什么时候调用拒绝处理程序…如果其中一个失败了,您想怎么做Wesome,非常感谢。我从未遇到过array reduce方法,现在仍在阅读它的具体工作原理,但您的第一个代码片段似乎可以工作,所以我很感激。谢谢您的建议。我确实需要将它们链接到b/c我正在调用的是文件系统,我相信我的个人承诺开始失败的原因是b/c太多的同时文件访问,所以我需要按顺序执行。我更喜欢reduce解决方案,而不是递归函数,因为它更干净。谢谢你的回答。@Bradley Bossard:尝试一下我刚刚发现的新解决方案,使用$。这使得代码非常简单。
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");
});
}