Angular2:异步上传文件数组

时间:2016-10-10 09:37:08

标签: javascript angular filereader

我正在尝试使用FileReader上传文件数组,这些文件是base64编码的并存储在数组中以供进一步处理。我正在努力理解我需要创建的模式,以确保所有文件都已上传,因为我必须等待onload事件处理程序触发。例如;

如果我将一组文件传递给以下函数,它将在文件实际上传之前解析承诺。

localUploads( event ) : any {

    var response = [];

    return new Promise( function(resolve, reject) {

        //Retrieve all the files from the FileList object
        var files = event.target.files;
        var response = [];

        if (files) {

            for (var i=0, f; f=files[i]; i++) {

                var r = new FileReader();

                r.onload = (function(f) {

                    return function(e) {

                        let contents = e.target['result'];

                        let file = {
                            name: f.name,
                            asset: contents,
                            private: false
                        };

                        console.log('we are pushing into the array');
                        response.push( file );
                    };

                })(f);


            }   
            resolve( response );
        }

        r.readAsText(f);
    });
}

有人可以建议新手吗?

非常感谢。

1 个答案:

答案 0 :(得分:1)

所有关于在正确的时间解决承诺。目前,您在循环完成后解决它,但这并不意味着所有项目都已处理完毕。我还没有使用过FileReader,但你应该能够做到这样的事情:

localUploads( event ) : any {

    var response = [];

    return new Promise(function(resolve, reject) {

        //Retrieve all the files from the FileList object
        var files = event.target.files;
        var response = [];

        if (files) {

            for (var i=0, f; f=files[i]; i++) {

                var r = new FileReader();
                r.onload = function(e) { // Possible clean-up?
                    let contents = e.target['result'];

                    let file = {
                        name: f.name,
                        asset: contents,
                        private: false
                    };

                    console.log('we are pushing into the array');
                    response.push( file );
                    if(response.length == files.length)
                    {
                        // Everything is done. Resolve the promise.
                        resolve( response );
                    }
                };
                // Moved here to be able to access r and f variables
                r.readAsText(f);
            }   
        }
    });
}

或使用$q的旧方式。

    var response = [];
    var dfd = $q.defer();

    //Retrieve all the files from the FileList object
    var files = event.target.files;
    var response = [];

    if (files) {
        for (var i=0, f; f=files[i]; i++) {
            var r = new FileReader();
            r.onload = function(e) { // Possible clean-up?
                let contents = e.target['result'];

                let file = {
                    name: f.name,
                    asset: contents,
                    private: false
                };

                console.log('we are pushing into the array');
                response.push( file );
                if(response.length == files.length)
                {
                    // Everything is done. Resolve the promise.
                    dfd.resolve(response);
                }
            };
            // Moved here to be able to access r and f variables
            r.readAsText(f);
        }   
    }
    else {
        // Possible resolve promise here to?
    }
    return dfd.promise;

请注意,您可能还想处理可能的错误。如果其中一个文件没有成功完成,则承诺永远不会得到解决。

您可能需要在onloadend而非onload中解析承诺。我真的无法从docs中找到答案。

var r = new FileReader();
r.onload = function(e) {
    if(response.length == files.length)
    {
        // Everything is done. Resolve the promise.
        dfd.resolve(response);
    }
}