Angular2:异步上传文件数组

Angular2 : Asynchronous upload array of files

我正在尝试使用 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);
    });
}

谁能请教新手吗?

非常感谢。

一切都是为了适时兑现诺言。目前您在循环完成时解决它,但这并不意味着所有项目都已处理。我没有使用过 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 instead of onload. I really cannot figure it out from the docs 中的承诺。

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