Javascript 如何知道在没有返回承诺的情况下成功执行了几个回调
!!!这个问题不是关于如何将承诺数组传递给Javascript 如何知道在没有返回承诺的情况下成功执行了几个回调,javascript,Javascript,!!!这个问题不是关于如何将承诺数组传递给when函数,因为file方法和onload返回承诺都不是重复的 我有一个自定义方法,它执行不返回承诺的异步函数。我的自定义方法确实返回了一个承诺。实现该功能的正确方法是什么?如例1所示使用超时,或如例2所示检查回调函数是否相等? 示例1: getAllFiles: function () { var def = $.Deferred(); var files = []; fileEntries.forEach(function(
when
函数,因为file
方法和onload
返回承诺都不是重复的
我有一个自定义方法,它执行不返回承诺的异步函数。我的自定义方法确实返回了一个承诺。实现该功能的正确方法是什么?如例1所示使用超时,或如例2所示检查回调函数是否相等?示例1:
getAllFiles: function () {
var def = $.Deferred();
var files = [];
fileEntries.forEach(function(fileEntry){
fileEntry.file(function (file) {
var reader = new FileReader();
reader.onload = function (e) {
files.push({
name: fileEntry.fullPath,
content: e.target.result
});
};
reader.readAsArrayBuffer(file);
});
});
//this resolves the deffered
var interval = setInterval(function(){
if (files.length === fileEntries.length) {
def.resolve(files);
clearInterval(interval);
}
}, 1000);
return def.promise();
}
示例2
getAllFiles: function () {
var def = $.Deferred();
var files = [];
fileEntries.forEach(function(fileEntry){
fileEntry.file(function (file) {
var reader = new FileReader();
reader.onload = function (e) {
files.push({
name: fileEntry.fullPath,
content: e.target.result
});
//this resolves the deffered
if (files.length === fileEntries.length) {
def.resolve(files);
clearInterval(interval);
}
};
reader.readAsArrayBuffer(file);
});
});
return def.promise();
}
只需对每个异步函数(onload
handler)做出承诺即可
(有必要对中的参数执行映射
ping操作,因为)
要回答您的实际问题:
实现该功能的正确方法是什么?如例1所示使用超时,或如例2所示检查回调函数中的相等性
从回调中执行。使用setInterval
进行轮询的结果是不受欢迎的(它速度较慢,不会捕获错误,甚至在错误情况下也不会泄漏)。看起来您正在使用jQuery,这意味着您可以利用它。请看@zzzzBov,我不知道在这里如何使用jQuery。你们能给我举个具体的例子吗?当
异步方法应该返回承诺时,给用户,但无论是文件
方法还是onload
都不返回承诺。第二个示例是不正确的,因为您多次解析延迟的(实际上是在每次循环迭代中)。根据您的要求,计时器可能不够可靠。您是否尝试过维护一个计数器,并且仅在读取最后一个文件时才解决延迟问题?感谢您花时间进行响应,这让我对Jquery的defferds:)有了新的了解。但是有一个问题,为什么要从文件回调返回def
,而不是def.promise()
?您可以这样做。延迟的实现Promise
接口,当使用该接口时,对其调用.Promise()
只会构造另一个对象。谢谢。但是def
可以在getAllFiles
函数外部解析,对吗?如果我们返回承诺
我们将阻止它。我也不明白为什么我需要这个var files=$.map(参数,函数(args){returnargs[0];})代码>因为参数已经包含对象数组。?我可以通过返回Array.prototype.slice.call(参数)将其简单地转换为实际数组代码>奇怪的是,当我像那样调用方法getAllFiles().done(函数(文件){})
变量files
只包含第一个对象,而不是然后返回的数组。知道为什么会发生这种情况吗?不,def
无法在getAllFiles
之外解决,因为我们不返回def
,而是通过$构建的承诺。这就是为什么在这里使用延期付款是省钱的原因。如果您将读取单个文件条目放在一个单独的函数中,那么您确实应该使用.promise()
。如果不仅仅是为了减少混乱,这里也可能更干净:-)
getAllFiles: function () {
var deferreds = fileEntries.map(function(fileEntry){
var def = $.Deferred();
fileEntry.file(function (file) {
var reader = new FileReader();
reader.onload = function (e) {
def.resolve({
name: fileEntry.fullPath,
content: e.target.result
});
};
reader.onerror = def.reject; // don't forget error handling!
reader.readAsArrayBuffer(file);
}, def.reject); // here as well
return def;
});
return $.when.apply($, deferreds).then(function() {
var files = $.map(arguments, function(args) { return args[0]; });
return files;
});
}