简体   繁体   English

对于循环,异步等待,承诺 - Javascript

[英]For loops, async await, promises - Javascript

I am trying to use a for loop to iterate through an array and perform an async function on each item.我正在尝试使用 for 循环遍历数组并在每个项目上执行异步 function。 I want this to happen in a sequential order and I don't want the next async function for the next item in the array to execute until the async function for the previous item has COMPLETED.我希望这按顺序发生,并且我不希望数组中下一个项目的下一个异步 function 执行,直到前一个项目的异步 function 完成。

I am using await and promises to try to do this.我正在使用 await 并承诺尝试这样做。 However, I must be doing something wrong because the code does not seem to be working right.但是,我一定做错了什么,因为代码似乎无法正常工作。 The for loop only seems to work once. for 循环似乎只工作一次。

Here is my code:这是我的代码:

function asyncFunc(i)
{
  //Here I am updating my database which is the async part of this function
  return db.collection("collection").doc("doc").update({
  })
  
  .then(function(){  
      let d = new Date();
      console.log(i + " async COMPLETED at: " + d.getTime());
      return new Promise((resolve, reject) => {
        resolve;
      });
  });
}

async function doWork()
{
  var numbers = [1,2,3,4];
  for(const i of numbers)
  {
    var d = new Date();
    console.log(i + " async CALLED at: " + d.getTime());
    await asyncFunc(i);
  }
}

doWork();

Here is the console output:这是控制台 output:

1 async CALLED at: 1594683980009
1 async COMPLETED at: 1594683980280

Why is this happening?为什么会这样?

So, you are returning two promises, which is a problem because you resolve one only to create a second which the main thread is then waiting on.因此,您返回了两个承诺,这是一个问题,因为您解决一个只是为了创建第二个,然后主线程正在等待。 All you have to do is return the promise that db.collection... gives you.您所要做的就是返回 db.collection... 给您的 promise。

Fundamentally, the problem is that the new promise you create isn't resolved properly.从根本上说,问题在于您创建的新 promise 没有正确解决。 You just say that the promise is (resolve, reject) => {resolve;} which is A) not even really a function and B) not going to resolve.您只是说 promise 是(resolve, reject) => {resolve;}这是 A) 甚至不是真正的 function 和 B) 不会解决。 Because you didn't call the resolve function.因为您没有调用解析 function。 Truly though, this promise should never have been created because it was completely unnecessary, so I would worry more about just handling promises with simple awaits and returns than bothering with creating them.确实,这个 promise 不应该被创建,因为它完全没有必要,所以我更担心只处理简单的等待和返回的承诺,而不是创建它们。 TL;DR Don't create a promise if there is already a promise that exists which you can use. TL;DR 如果已经存在可以使用的 promise,请不要创建 promise。

This code should work:此代码应该可以工作:

function asyncFunc(i)
{
  //Here I am updating my database which is the async part of this function
  return db.collection("collection").doc("doc").update({
  })
  .then(() =>{  
      let d = new Date();
      console.log(i + " async COMPLETED at: " + d.getTime());
  });
}

async function doWork()
{
  var numbers = [1,2,3,4];
  for(const i of numbers)
  {
    var d = new Date();
    console.log(i + " async CALLED at: " + d.getTime());
    await asyncFunc(i);
  }
}

doWork();

For the sake of clarity regarding the actual issue you ran into, the problem is with this block of your code:为了清楚您遇到的实际问题,问题在于您的代码块:

  return new Promise((resolve, reject) => {
    resolve;
  });

The problem is that resolve needs to be a function that actually executes.问题是resolve需要是实际执行的 function。 Thus what you needed was this:因此,您需要的是:

  return new Promise((resolve, reject) => {
    resolve();
  });

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

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