Javascript .then()承诺块不适用于WAIT

Javascript .then()承诺块不适用于WAIT,javascript,reactjs,firebase,promise,async-await,Javascript,Reactjs,Firebase,Promise,Async Await,我正在与Firebase合作。我正在使用异步firebase函数获取我添加的文件的下载URL。这个函数在for循环中运行多次,为了使所有内容保持同步,我使用“async”和“await”等待添加文件,然后再转到循环中的下一个条目。但我填充的数组“uploads”最终在整个循环完成后会变成空的。因为等待在里面,所以它不起作用。如果没有,我怎么做 _handlePost = () => { var fs = this.props.firebase.getFS(); let u

我正在与Firebase合作。我正在使用异步firebase函数获取我添加的文件的下载URL。这个函数在for循环中运行多次,为了使所有内容保持同步,我使用“async”和“await”等待添加文件,然后再转到循环中的下一个条目。但我填充的数组“uploads”最终在整个循环完成后会变成空的。因为等待在里面,所以它不起作用。如果没有,我怎么做

 _handlePost = () => {
    var fs = this.props.firebase.getFS();
    let uploads = [];

    // if any files attached to post
    if (this.state.allFiles.length > 0) {
        const currentComponent = this;
        let files = this.state.allFiles;
        for (let i=0; i<files.length; i++) {
            var file = files[i];
            var type = file.type;
            var file_parts = type.split("/");
            var type = "." + file_parts[1];
            var cat = file_parts[0];
            var file_path = '';

            // save to correct firebase storage folder
            if (cat === "image")
                file_path = "image/";
            else if (cat === "video")
                file_path = "videos/";
            else
                file_path = "test_file_upload";
            const uploadtask = currentComponent.props.firebase.getStorageRef(file_path + file.name).put(file);
            uploadtask.on(
                'state_changed',
                null,
                (error) => { console.log(error); },
                () => {
                    currentComponent.props.firebase.getStorageRef(file_path).child(file.name).getDownloadURL()
                    .then(function(url) {
                        // add to content collection
                        fs.collection("content").add({
                            category: cat,
                            file_name: file.name,
                            file_type: type,
                            time_uploaded: new Date(Date.now()),
                            user_id: currentComponent.props.userId,
                            url_link: url
                        })
                        .then(async function(doc) {
                            console.log("Added to content collection!");
                            const attachment = {
                                category: type,
                                content_id: doc.id,
                                url_link: url
                            };
                            uploads.push(attachment);
                        });
                    });    
                }
            );
        };
    }
    console.log("Done");
    console.log(uploads);
    // add wall_posts to database
    fs.collection("wall_posts").add({
        attachments: uploads,
        body_text: this.state.post_text,
        posterid: this.props.userId,
        time_posted: new Date(Date.now()),
        user_id_wall: this.props.userId
    })
    .then(function() {
        console.log("Post successful!");
    });
  }
\u handlePost=()=>{
var fs=this.props.firebase.getFS();
让上传=[];
//如果有任何附加到post的文件
如果(this.state.allFiles.length>0){
const currentComponent=此;
让files=this.state.allFiles;
对于(设i=0;i{console.log(error);},
() => {
currentComponent.props.firebase.getStorageRef(文件路径).child(文件名).getDownloadURL()
.then(函数(url){
//添加到内容集合
fs.集合(“内容”)。添加({
类别:猫,,
文件名:file.name,
文件类型:类型,
上传时间:新日期(Date.now()),
用户id:currentComponent.props.userId,
url\u链接:url
})
.then(异步函数(doc){
log(“添加到内容集合!”);
常量附件={
类别:类型,,
content\u id:doc.id,
url\u链接:url
};
上传。推送(附件);
});
});    
}
);
};
}
控制台日志(“完成”);
console.log(上传);
//将墙贴添加到数据库
财政司司长收藏(“墙柱”)。添加({
附件:上传,
正文文本:this.state.post文本,
posterid:this.props.userId,
发布时间:新日期(Date.now()),
user\u id\u wall:this.props.userId
})
.然后(函数(){
log(“Post successful!”);
});
}
使用该语句,而不是用于循环的任何其他语句。这将允许在进入下一个迭代之前解决每个迭代中的承诺

// I guess from your code that you're iterating through a FileList? Could be an array or any sort of list.
for await (file of files) {
  // ...
}

问题是,
forEach(…)
并没有等待承诺完成:它迭代您的条目并开始n个承诺,这些承诺在您
fs.collection(“wall_posts”).add(…)
之前都不是
解析的。我正在重写您的
forEach()
和函数调用,使其以更惯用的异步/等待样式运行:

async function chooseAName(){
 let files = this.state.allFiles;
 for (let i = 0; i < files.length; i++){
      const file = files[i]; // this is an assumption
      const url = await  currentComponent.props.firebase
      .getStorageRef(file_path) //where is this set in your code? maybe it should be file.path?
      .child(file.name)
      .getDownloadURL();     

        // add to content collection
      const doc = await fs
          .collection('content')
          .add({
            category: cat,
            file_name: file.name,
            file_type: type,
            time_uploaded: new Date(Date.now()),
            user_id: currentComponent.props.userId,
            url_link: url,
          });

            console.log('Added to content collection!');
            const attachment = {
              category: type,
              content_id: doc.id,
              url_link: url,
            };
            uploads.push(attachment);

}
await fs.collection("wall_posts").add({
        attachments: uploads,
        body_text: this.state.post_text,
        posterid: this.props.userId,
        time_posted: new Date(Date.now()),
        user_id_wall: this.props.userId
    });

console.log("Post successful!");
异步函数chooseAName(){ 让files=this.state.allFiles; for(设i=0;i
为什么要将链接和等待混为一谈?您所说的“出来时是空的”是什么意思?@jonrsharpe我刚开始只是链接。我的意思是,在承诺完成后,“上传”数组不会被填充。它是在其他函数之后完成的。因此,我尝试了异步/等待,看看是否有效。请同时发布包装此函数调用的
for
循环。甚至整个函数ion,它为循环包装了
,这是很有用的,您如何准确地确定“在承诺完成后”?给出一个。@jonrsharpe我在控制台上打印出来,之后运行的代码显示firebase数据库中没有数据。我在问题中添加了代码。我认为收集调用将在所有上传完成后进行,因为它需要整个列表。@jonrsharpe-我认为你是对的,观察得很好,我编辑了我的答案以反映t帽子