如何使用 promise 等待函数执行

How to use promise in order to wait for a function to execute

我有一段异步 javascript 代码需要执行,然后可以执行下一个语句

function getEventData() {
            return new Promise(resolve => {
              eventList.forEach((event) => {
                db.collection('Events').doc(event)?.collection('registeredStudents')?.get()
                .then((querySnapshot) => {
                  eventData.push({"id": event, "number": querySnapshot.size})
                })
              })
              resolve();
            })
          }
          getEventData().then(console.log(eventData))

eventList 是一个包含 17 个元素的数组,它在数据库中列出大约 17 次,效率很低,但我别无选择,所以不得不这样做。无论如何,在控制台中我记录了一个空数组。我该如何解决。 PS:我是异步 javascript 和 promises 的新手。

您可以使用 Promise.all():

function getEventData() {
  return new Promise(async (resolve) => {
    await Promise.all(
      eventList.map(async (event) => {
        let querySnapshot = await db.collection('Events').doc(event)?.collection('registeredStudents')?.get()
        eventData.push({"id": event, "number": querySnapshot.size})
      })
    );
    resolve();
  })
}

getEventData().then(console.log(eventData))

这是一个关于如何在循环中使用 promises 的简单演示。我正在执行的异步操作正在“休眠”(也就是在一切都“休眠”之前什么都不会发生)..

const sleepTimes = [1, 2, 3];
const promises = [];

sleepTimes.forEach(time => {
  const promise = new Promise((resolve, reject) => {
    return setTimeout(resolve, time * 1000, time * 1000);
  });
  promises.push(promise);
});

console.log(promises);

Promise.all(promises).then((values) => {
  document.body.innerHTML = values;
});

这意味着您的函数应该类似于:

function getEventData() {
  const promises = [];
  eventList.forEach((event) => {
    // I assume this already returns a promise, so there's no need to wrap it in one
    const promise = db.collection("Events").doc(event)?.collection("registeredStudents")?.get();
    promises.push(promise);
  });
  return Promise.all(promises);
}

getEventData().then((values) => console.log(values));

处理你的问题的正确方法不是使用带有 resolve 的 new Promise,而是使用 async await。 当您等待承诺时,它会等待它解决并 returns 结果(不是承诺!),然后再继续下一行。 调用时等待承诺 returns 承诺的函数。 Promise.all 将多个承诺合并为一个,因此您可以等待多个承诺同时解决,并同时 运行(异步)。

async function getEventData(eventList) {
    try {
        const eventData = [];

        await Promise.all(eventList.map(async event => {
            const querySnapshot = await db.collection('Events').doc(event)?.collection('registeredStudents')?.get();
            eventData.push({"id": event, "number": querySnapshot.size});
        }));
        
        console.log(eventData)
    } catch (exception) {
      // error handling
    }
}