Javascript JS等待函数中的几个事件完成

Javascript JS等待函数中的几个事件完成,javascript,jquery,events,Javascript,Jquery,Events,我有一个上传图像并在页面上显示的功能。我应该如何等待函数完成 $("#images").change(function(){ updateArray(this); addImages(); }); function updateArray(inp) { for(var i=0,file; file = inp.files[i]; i++) { var reader = new FileRea

我有一个上传图像并在页面上显示的功能。我应该如何等待函数完成

$("#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()

有几种方法可以实现这一点,但是如果您使用jQuery(看起来是),我建议您查看承诺(请参阅:)


它们是延迟回调的一个更现代的范例,延迟回调有一些语义处理,用于基于成功完成、失败和将始终处理的函数来执行函数。

有几种方法可以实现这一点,但是如果您使用jQuery(看起来是),我建议您查看承诺(见:)

它们是一种更现代的延迟回调范例,具有一些语义处理,用于基于成功完成、失败和将始终处理的函数来执行函数。

我将在此处使用jQuery。这将允许您等待每个
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);
}
这将为每个
文件读取器
创建一个新的延迟对象。当每个文件读取器完成时,将解析其各自的延迟对象。
$。当使用
将所有延迟合并为一个时。因此,在
.change()
中,您可以简单地执行以下操作:

$("#images").change(function(){
    updateArray(this).done(function(){
        addImages();
    });
});
另外,您还可以将参数传递给
resolve()
,以便在
.done()
回调中使用。因此,您可以执行
d.resolve(evt.target.result);
而不是将参数附加到
图像
数组中

然后在
.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();
    });
});
我会在这里使用jQuery。这将允许您等待每个
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);
}
这将为每个
文件读取器
创建一个新的延迟对象。当每个文件读取器完成时,将解析其各自的延迟对象。
$。当使用
将所有延迟合并为一个时。因此,在
.change()
中,您可以简单地执行以下操作:

$("#images").change(function(){
    updateArray(this).done(function(){
        addImages();
    });
});
另外,您还可以将参数传递给
resolve()
,以便在
.done()
回调中使用。因此,您可以执行
d.resolve(evt.target.result);
而不是将参数附加到
图像
数组中

然后在
.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();
    });
});

什么是
updateArray
?它是同步的?异步的?如果没有
updateArray
函数的定义,我们就帮不了你。你能给我们看看updateArray函数的代码吗?通常你是通过JS.P.s中的回调来实现的。你为什么要做
images[images.length]=…;
?只要做
images.push就行了(evt.target.result);
什么是
updateArray
?它是同步的?异步的?如果没有
updateArray
函数的定义,我们就帮不了你。你能给我们看看updateArray函数的代码吗?通常你是通过JS.P.s中的回调来实现的。你为什么要做
images[images.length]=…;
?只需执行
images.push(evt.target.result);
。我不知道
images
应该是什么,但我建议放弃它并使用
d.resolve(evt.target.result)
来代替-获得
图像作为返回的承诺的结果。@Bergi:不错的主意:-)我不知道
图像应该是什么,但我建议放弃它,使用
d.resolve(evt.target.result)
来代替-将
图像作为返回的承诺的结果。@Bergi:不错:-)