在这种情况下,为什么我的函数没有等待promise.all()的结果?我在这里错过了什么?

问题描述 投票:0回答:1

我有一个函数可以循环访问一系列帐户值并返回每个帐户的最新值。然后我使用 reduce() 将这些数字减少到总数。

此功能有时有效有时无效。我没有收到任何错误,我只是从reduce函数返回0。

数据存储在 Google Firestore 数据库中,应用程序是用 React 编写的。

  async function getValueofPortfolio() {
    const values = await Promise.all(
      Object.keys(accounts).map((account) => getPerformanceForAccount(account))
    ).then((values) => values.map((el) => el[0].value));

    const reduce = values.reduce(
      (accumulator, currentValue) => accumulator + currentValue,
      0
    );

    return currency(reduce);
  }

getValueofPortfolio()中引用的其他函数:

const getPerformanceForAccount = async (accountId) => {
    return getPerformanceFromFireStore(accountId).then((data) => {
      //... a lot of code transforming the data which is irrelevant for this question.
      return data;
    });
  };

在我的应用程序中调用 getPerformanceForAccount() 没有问题。

  async function getPerformanceFromFireStore(accountId) {
    // Query a reference to a subcollection
    const querySnapshot = await getDocs(
      collection(db, "userData", user.uid, "accounts", accountId, "performance")
    );
    let data = {};
    if (querySnapshot.empty) {
      console.log("item empty");
      return data;
    } else {
      querySnapshot.forEach((d) => {
        data[d.id] = d.data();
      });
    }
    return data;
  }

在我的应用程序中也可以毫无问题地调用 getPerformanceFromFireStore()。

我对使用异步函数和数据库相当陌生,因此我们将不胜感激。

javascript async-await promise
1个回答
0
投票

仔细检查 getPerformanceFromFirestore() 返回的数据结构以及 getValueofPortfolio() 中的处理方式。减少值时,数据结构中的任何差异都可能导致意外结果。

如果任何帐户没有数据或获取的数据为空,则可能会导致总和为零。确保您正确处理空值。

虽然您将 Await 与 Promise.all() 一起使用,但建议显式处理 Promise,而不是将 wait 与 then() 链混合。这有时会导致意外的行为。

async function getValueofPortfolio() {
  try {
    const values = await Promise.all(
      Object.keys(accounts).map((account) => 
       getPerformanceForAccount(account))
    );

    const mappedValues = values.map((el) => el[0].value); // Assuming each 
    account has at least one value
    const total = mappedValues.reduce((accumulator, currentValue) => 
    accumulator + currentValue, 0);

    return currency(total);
  } catch (error) {
    console.error("Error fetching or processing data:", error);
    // Handle error appropriately
    // You might choose to return a default value or rethrow the error
    throw error;
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.