Firebase存储:返回URL的顺序与订购文件的顺序相同

时间:2020-02-23 07:40:42

标签: javascript firebase promise firebase-storage


我正在Firebase上开发一个Web应用程序,并且正在编写一个功能以上传到Firebase存储并返回用户上传文件的下载URL。这些文件有顺序,我的意图是按文件的顺序存储URL。
下面的函数返回URL,但它们的顺序不正确。我想这与文件大小和上传每个文件并下载链接所需的时间不同有关。
如何确保URL按预期顺序存储在Promise中?例如我可以想到只有在promise中存储了先前文件的URL之后才调用storageRef.put方法,但是我是编程新手,不知道如何解决它……请帮帮忙!

function url_array_get(){
    const promises = [];
    const user=firebase.auth().currentUser;
    const filez=review_photo.files;
    const files=Array.from(filez); //This is an array of files with specific ordering
    files.forEach(function(file) { //The files are uploaded in the intended order
       let storageRef=firebase.storage().ref('data/'+user.uid+'/posts/'+file.name);
         promises.push(
             storageRef.put(file).then(function(snapshot){
                 return snapshot.ref.getDownloadURL()
             })
         )
    })
    return Promise.all(promises); //The returned URLs are not in the intended order
}

1 个答案:

答案 0 :(得分:0)

您必须利用以下事实:Promise.All()中,“返回值将按照传递的Promises的顺序进行,而与完成顺序无关”。

使用两次Promise.all(),您将达到目标。以下应该可以解决问题(未试用)。

function url_array_get() {

    const filesPromises = [];
    const user = firebase.auth().currentUser;
    const filez = review_photo.files;
    const files = Array.from(filez); //This is an array of files with specific ordering

    const urlsPromises = [];

    files.forEach(function (file) { //The files are uploaded in the intended order
        const storageRef = firebase.storage().ref('data/' + user.uid + '/posts/' + file.name);

        filesPromises.push(
            storageRef.put(file)
        )
    })
    return Promise.all(filesPromises)
        .then(function (uploadTasks) {

            uploadTasks.forEach(function (uploadTask) {
                urlsPromises.push(uploadTask.snapshot.ref.getDownloadURL())
            })

            return Promise.all(urlsPromises)
        })
        .then(function (urls) {

            // urls is the Array of all download URLs in the right order
            urls.forEach(function (url) {
                console.log(url);
            })

        })

}