我有一个执行异步函数的自定义方法,该函数不返回承诺。我的自定义方法确实返回了一个承诺。实现该功能的正确方法是什么 - 使用超时(如示例 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();
}
这个问题不是关于如何将 Promise 数组传递给
when
函数,因为 file
方法和 onload
都不会返回 Promise。
简单地make为每个异步函数(
onload
处理程序)做出承诺!
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;
});
}
(对
map
中的参数进行 then
ping 是必要的,因为 jQuery 的 $.when
结果太难看了)
回答您的实际问题:
实现该功能的正确方法是什么 - 使用超时(如示例 1 所示)或检查回调函数中的相等性(如示例 2 所示)?
从回调中执行此操作。使用
setInterval
进行轮询结果是被鄙视的(它速度较慢,不会捕获错误,甚至在错误情况下会泄漏)。