Javascript .then()承诺块不适用于WAIT
我正在与Firebase合作。我正在使用异步firebase函数获取我添加的文件的下载URL。这个函数在for循环中运行多次,为了使所有内容保持同步,我使用“async”和“await”等待添加文件,然后再转到循环中的下一个条目。但我填充的数组“uploads”最终在整个循环完成后会变成空的。因为等待在里面,所以它不起作用。如果没有,我怎么做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
_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帽子