繁体   English   中英

在执行下一行之前等待 foreach 完成

[英]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,
              });
            });
        
          };

感谢我能得到的任何帮助。 谢谢!

首先,当您使用asyncawait关键字基本上替换了.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

当那个大承诺解析(使用.thenawait )时,它将有一个数组作为解析值,并且该数组将包含来自原始承诺的所有解析值。 换句话说,如果你这样做:

const foo = await Promise.all(arrayOfPromises);

然后foo将是包含什么作为通过了的阵列.then / await值对于每个在承诺传入的arrayOfPromises

javascript 代码,默认情况下将在移动到下一行之前完成。 这是它的自然行为。 如果您只是正常编写代码,它将一次执行一行。

您在代码中添加了“异步”标签,然后要求它不以异步方式运行,这完全符合逻辑。

如果您希望代码以完成 foreach 的方式执行,只需不要添加任何异步标记。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM