简体   繁体   English

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

[英]wait for foreach to finish before executing next lines

I want the code to wait for the foreach function to complete before going to the next line to perform the if statement on the counter number.我希望代码在转到下一行以对计数器编号执行 if 语句之前等待 foreach 函数完成。 I am sure I have to put a Promise somewhere... but I also thought that .then() would do the trick?我确定我必须在某处放置一个 Promise ......但我也认为 .then() 可以解决问题?

It appears there are examples of this but I am not able to figure this one out or where Im going wrong here:似乎有这样的例子,但我无法弄清楚这个或者我在这里出错的地方:

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

Appreciate any help I can get.感谢我能得到的任何帮助。 Thanks!谢谢!

First off, when you're using async , the await keyword essentially replaces .then .首先,当您使用asyncawait关键字基本上替换了.then In other words:换句话说:

ref
        .collection(‘foo’)
        .where(‘open’, '==', true)
        .get()
        .then(async snapshot => {
        // indented code that uses snapshot

can become:可以变成:

const snapshot = await ref
        .collection(‘foo’)
        .where(‘open’, '==', true)
        .get();
// not-indented code that uses snapshot

When you use await in this way the browser will pause your code and "restart it" when the request returns, the exact same way as with .then (because it's literally just syntactic sugar on top of promises).当您以这种方式使用await ,浏览器暂停您的代码并在请求返回时“重新启动它”,与使用.then方式完全相同(因为它实际上只是 Promise 之上的语法糖)。

Second, as @Doug Stevenson noted in a comment, forEach doesn't pause on promises, so when doing asynchronous work what you really want to do is use map instead of a forEach , and combine it with Promise.all , like so:其次,正如@Doug Stevenson 在评论中指出的那样, forEach不会暂停承诺,因此在进行异步工作时,您真正想做的是使用map而不是forEach ,并将其与Promise.all结合,如下所示:

await Promise.all(someArray.map(async x => ...))

In other words, you want your (formerly) forEach callback to return a promise, and map lets you do that (vs. forEach returns nothing).换句话说,您希望您的(以前的) forEach回调返回一个承诺,而map允许您这样做(相对于forEach返回任何内容)。 Promise.all will convert each of those individual promises into one big one, which you can then await or chain a .then off. Promise.all会将这些单独的承诺中的每一个转换为一个大的承诺,然后您可以await或链接一个.then

When that big promise resolves (either with .then or await ) it will have an array as a resolved value, and that array will contain all of the resolved values from the original promises.当那个大承诺解析(使用.thenawait )时,它将有一个数组作为解析值,并且该数组将包含来自原始承诺的所有解析值。 In other words if you do:换句话说,如果你这样做:

const foo = await Promise.all(arrayOfPromises);

then foo will be an array containing what would have been passed as the .then / await value for each of the promises in the passed-in arrayOfPromises .然后foo将是包含什么作为通过了的阵列.then / await值对于每个在承诺传入的arrayOfPromises

javascript code, by default will finish before moving on to the next line. javascript 代码,默认情况下将在移动到下一行之前完成。 That's its natural behavior.这是它的自然行为。 It you just write code normally it will execute one line at a time.如果您只是正常编写代码,它将一次执行一行。

you have added a "async" tag to you code and then asked for it to not run in an async way, which is note entirely logical.您在代码中添加了“异步”标签,然后要求它不以异步方式运行,这完全符合逻辑。

if you want your code to execute in a way that it finishes the foreach, simply don't add any async tags.如果您希望代码以完成 foreach 的方式执行,只需不要添加任何异步标记。

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

相关问题 如何在继续下一行代码之前等待 .map() 完成执行 - How to wait for .map() to finish executing before continuing on to next lines of code 在执行下一个函数之前等待循环完成 - wait for for loop to finish before executing next function 等待循环完成,然后再执行下一行 - Wait for loop to finish before executing next line Javascript在执行下一行之前不等待函数完成 - Javascript doesn't wait for function to finish before executing next line 在执行下一个函数之前等待循环完成填充数组 - wait for loop to finish populating array before executing next function Javascript在执行下一个命令之前不会等待JQuery动画完成 - Javascript will not wait for JQuery animation to finish before executing next command Javascript:等待循环中的函数在下一次迭代之前完成执行 - Javascript: wait for function in loop to finish executing before next iteration 等待 Google 地球完成加载,然后在 matlab 中执行下一个命令 - wait for Google Earth to finish loading before executing next command in matlab 如何在运行下一个代码之前等待异步 JSZip .forEach() 调用完成? - How to wait for asynchronous JSZip .forEach() call to finish before running next code? 等待功能完成后再执行其余操作 - Wait for function to finish before executing the rest
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM