Javascript循环不等待Firebase完成上传多个文件

时间:2018-12-17 06:32:12

标签: javascript firebase firebase-storage

我正在尝试上传多个文件,然后在所有文件上传之后执行一些代码,但是我的循环不会等到每次上传完成之后。

迭代文件:

//files is an array of local files from a <input type="file">
for (var i = 0, f; f = files[i]; i++) {
     var imageFile = files[i];
     var response = uploadImageAsPromise(imageFile);
}
//after completing all uploads, execute some code here
console.log("Finished uploading all files");

上传功能:

function uploadImageAsPromise(imageFile) {
    var image_id = new Date().valueOf();
    var storageRef = firebase.storage().ref().child(image_id + "");
    return new Promise(function (resolve, reject) {
        //Upload file
        var task = storageRef.put(imageFile);

        //Update progress bar
        task.on('state_changed',
            function progress(snapshot) {
                var percentage = snapshot.bytesTransferred / snapshot.totalBytes * 100;
            },
            function error(err) {
                console.log(err);
            },
            function complete() {
                task.snapshot.ref.getDownloadURL().then(function (downloadURL) {
                    var picture = downloadURL;
                    console.log("Finished uploading file: " + image_id);
                });
            }
        );
    });
}

但是,即使在所有文件上传之前,我的第一个控制台日志也会被执行。如何让它等到一切完成?

2 个答案:

答案 0 :(得分:1)

第一个问题是您的path.join函数。它永远不会真正解决它所创造的承诺,因此任何等待结果的事情都会永远等待。

这大概应该可以工作:

uploadImageAsPromise

您没有做任何事情等待诺言完成,因此,很自然,下一个代码将继续执行。

要并行上传文件并等待文件完成

使用async / await(如果您的执行环境支持它):

function uploadImageAsPromise(imageFile) {
    var image_id = new Date().valueOf();
    var storageRef = firebase.storage().ref().child(image_id + "");
    return new Promise(function (resolve, reject) {
        //Upload file
        var task = storageRef.put(imageFile);

        //Update progress bar
        task.on('state_changed',
            function progress(snapshot) { },
            function error(err) { reject(err); },
            function complete() { resolve(task); }
        );
    }).then(function (task) {
        return task.snapshot.ref.getDownloadURL();
    }).then(function (downloadURL) {
        console.log("Finished uploading file: " + image_id);

        return downloadURL;
    });
}

没有异步/等待状态:

async function uploadFiles(files) {
   await Promise.all(files.map(uploadImageAsPromise));
}


async function someOuterFunction(files) {
   await uploadFiles(files);

   console.log('All done!');
}

someOuterFunction(files);

要顺序上传文件并等待文件完成

使用async / await(如果您的执行环境支持它):

Promise.all(files.map(uploadImageAsPromise))
    .then(function () {
        console.log('All done!');
    });

没有异步/等待状态:

async function uploadFiles(files) {
    for (let file of files) {
        await uploadImageAsPromise(file);
    }
}

async someOuterFunction(files) {
     await uploadFiles(files);

     console.log('All done!');
}

someOuterFunction(files);

答案 1 :(得分:1)

您需要等待所有诺言解决。您可以使用Promise.alldocs here)同时执行此操作。

var promises = [];

for (var i = 0, f; f = files[i]; i++) {
     var imageFile = files[i];
     promises.push(uploadImageAsPromise(imageFile));
}

Promise.all(promises).then(function(values) {
    //after completing all uploads, execute some code here
    console.log("Finished uploading all files", values);
}).catch(function(error) {
    console.log("One of the promises rejected.", error);
});