我有这堂课:
(function(){
"use strict";
var FileRead = function() {
this.init();
};
p.read = function(file) {
var fileReader = new FileReader();
var deferred = $.Deferred();
fileReader.onload = function(event) {
deferred.resolve(event.target.result);
};
fileReader.onerror = function() {
deferred.reject(this);
};
fileReader.readAsDataURL(file);
return deferred.promise();
};
lx.FileRead = FileRead;
}(window));
在循环中调用该类:
var self = this;
$.each(files, function(index, file){
self.fileRead.read(file).done(function(fileB64){self.fileShow(file, fileB64, fileTemplate);});
});
我的问题是,有没有办法在循环完成后调用一个方法,并且self.fileRead
已经返回它,因为循环中的所有内容都被延迟了?
我希望它调用该方法,即使一个或多个延迟失败。
答案 0 :(得分:3)
$。when允许你将多个promises包装成一个。其他承诺库有类似的东西。构建一个由fileRead.read返回的promise数组,然后将该数组传递给$ .when并将/ done / fail / always方法挂钩到.when返回的promise中
// use map instead of each and put that inside a $.when call
$.when.apply(null, $.map(files, function(index, file){
// return the resulting promise
return self.fileRead.read(file).done(function(fileB64){self.fileShow(file, fileB64, fileTemplate);});
}).done(function() {
//now everything is done
})
答案 1 :(得分:0)
var self = this;
var processFiles = function (data) {
var promises = [];
$.each(files, function (index, file) {
var def = data.fileRead.read(file);
promises.push(def);
});
return $.when.apply(undefined, promises).promise();
}
self.processFiles(self).done(function(results){
//do stuff
});
$.when
说“当所有这些承诺得到解决时......做点什么”。它需要无限(可变)数量的参数。在这种情况下,你有一系列的承诺;
答案 2 :(得分:0)
我知道这已关闭,但正如$.when
的文档所述:在多个Deferreds案例中,其中一个Deferred被拒绝,jQuery。当立即为其激活failCallbacks延期。 (立即强调是我的)
如果你想完成所有 Deferreds即使失败了,我相信你需要在下面这些行中提出你自己的插件。 $.whenComplete
函数需要一个返回JQueryPromise
的函数数组。
var whenComplete = function (promiseFns) {
var me = this;
return $.Deferred(function (dfd) {
if (promiseFns.length === 0) {
dfd.resolve([]);
} else {
var numPromises = promiseFns.length;
var failed = false;
var args;
var resolves = [];
promiseFns.forEach(function (promiseFn) {
try {
promiseFn().fail(function () {
failed = true;
args = arguments;
}).done(function () {
resolves.push(arguments);
}).always(function () {
if (--numPromises === 0) {
if (failed) {
//Reject with the last error
dfd.reject.apply(me, args);
} else {
dfd.resolve(resolves);
}
}
});
} catch (e) {
var msg = 'Unexpected error processing promise. ' + e.message;
console.error('APP> ' + msg, promiseFn);
dfd.reject.call(me, msg, promiseFn);
}
});
}
}).promise();
};
答案 3 :(得分:0)
为了满足要求,“即使一个或多个延迟失败也要调用方法”你理想地想要一个.allSettled()
方法,但是jQuery没有特定的糖,所以你必须这样做一份DIY工作:
您可以使用$.allSettled()
和.when()
的组合查找/编写.then()
实用程序或达到相同的效果,如下所示:
var self = this;
$.when.apply(null, $.map(files, function(index, file) {
return self.fileRead.read(file).then(function(fileB64) {
self.fileShow(file, fileB64, fileTemplate);
return fileB64;//or similar
}, function() {
return $.when();//or similar
});
})).done(myMethod);
如果它存在,$.allSettled()
会在内部做类似的事情。
接下来,“在myMethod中,如何区分错误的良好反应?”,但这是另一个问题:)