我有一个上传图片并在页面上显示的功能。我该如何等待功能完成?
$("#images").change(function(){
updateArray(this);
addImages();
});
function updateArray(inp)
{
for(var i=0,file; file = inp.files[i]; i++)
{
var reader = new FileReader();
reader.onload = function (evt)
{
images[images.length] = evt.target.result;
}
reader.readAsDataURL(file);
}
}
我想在updateArray()中的所有事件完成后调用addImages()
答案 0 :(得分:4)
我会在这里使用jQuery的deferred/promises。这将允许您等到每个 onload
完成,然后触发回调。
以下是一个例子:
function updateArray(inp)
{
var promises = [];
for(var i=0,file; file = inp.files[i]; i++)
{
var reader = new FileReader(),
d = new $.Deferred();
promises.push(d);
// Make sure we "capture" the correct 'd'
(function(d){
reader.onload = function (evt)
{
images.push(evt.target.result);
d.resolve();
}
}(d));
reader.readAsDataURL(file);
}
return $.when.apply($, promises);
}
这将为每个FileReader
创建一个新的延迟对象。当每一个完成时,其相应的延期将被解决。 $.when
用于将所有延迟合并为一个。因此,在您的.change()
中,您可以这样做:
$("#images").change(function(){
updateArray(this).done(function(){
addImages();
});
});
P.S。您还可以将参数传递给resolve()
以在.done()
回调中使用。因此,您可以执行images
。
d.resolve(evt.target.result);
数组
(function(d){
reader.onload = function (evt)
{
d.resolve(evt.target.result);
}
}(d));
然后在.done()
中,你可以这样做:
$("#images").change(function(){
updateArray(this).done(function(){
// Each '.resolve' added a new parameter to here, let's get them all
images = [].slice.call(arguments, 0);
addImages();
});
});
答案 1 :(得分:1)
有几种方法可以解决这个问题,但是如果你使用jQuery(你似乎是这样),我建议你研究一下promises(参见:http://api.jquery.com/promise/)。
对于延迟回调,它们是一种更现代的范例,它具有一些基于成功完成,失败以及将始终处理的函数执行函数的语义处理。