[英]How to wait for .map() to finish executing before continuing on to next lines of code
[英]wait for foreach to finish before executing next lines
我希望代码在转到下一行以对计数器编号执行 if 语句之前等待 foreach 函数完成。 我确定我必须在某处放置一个 Promise ......但我也认为 .then() 可以解决问题?
似乎有这样的例子,但我无法弄清楚这个或者我在这里出错的地方:
async getSomeData () {
const data = [];
const ref = fire.firestore();
ref
.collection(‘foo’)
.where(‘open’, '==', true)
.get()
.then(async snapshot => {
let count = 0;
snapshot
.docs
.forEach(async doc => {
const {foo, bar} = doc.data();
const number_count = await this.getNumber(doc.id);
if (number_count >= 1){
count++;
data.push({
foo,
bar
});
this.setState({
data : data,
});
}
})
.then() ?????
**//THIS IS EXECUTING BEFORE THE FOREACH FINISHES**
if(count==0){
this.setState({
isLoading: false,
noStores: true
});
}
}).catch(error => {
console.log(error);
//if fails
this.setState({
noStores : true,
});
});
};
感谢我能得到的任何帮助。 谢谢!
首先,当您使用async
, await
关键字基本上替换了.then
。 换句话说:
ref
.collection(‘foo’)
.where(‘open’, '==', true)
.get()
.then(async snapshot => {
// indented code that uses snapshot
可以变成:
const snapshot = await ref
.collection(‘foo’)
.where(‘open’, '==', true)
.get();
// not-indented code that uses snapshot
当您以这种方式使用await
,浏览器将暂停您的代码并在请求返回时“重新启动它”,与使用.then
方式完全相同(因为它实际上只是 Promise 之上的语法糖)。
其次,正如@Doug Stevenson 在评论中指出的那样, forEach
不会暂停承诺,因此在进行异步工作时,您真正想做的是使用map
而不是forEach
,并将其与Promise.all
结合,如下所示:
await Promise.all(someArray.map(async x => ...))
换句话说,您希望您的(以前的) forEach
回调返回一个承诺,而map
允许您这样做(相对于forEach
返回任何内容)。 Promise.all
会将这些单独的承诺中的每一个转换为一个大的承诺,然后您可以await
或链接一个.then
。
当那个大承诺解析(使用.then
或await
)时,它将有一个数组作为解析值,并且该数组将包含来自原始承诺的所有解析值。 换句话说,如果你这样做:
const foo = await Promise.all(arrayOfPromises);
然后foo
将是包含什么将作为已通过了的阵列.then
/ await
值对于每个在承诺传入的arrayOfPromises
。
javascript 代码,默认情况下将在移动到下一行之前完成。 这是它的自然行为。 如果您只是正常编写代码,它将一次执行一行。
您在代码中添加了“异步”标签,然后要求它不以异步方式运行,这完全符合逻辑。
如果您希望代码以完成 foreach 的方式执行,只需不要添加任何异步标记。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.