首页 > 解决方案 > 当我试图在一个承诺内计算一个价格时返回一个零值

问题描述

我试图从 API(firebase)中提取数据并取回正确的数据,但是当我尝试解决 Promise 中的最终价格时,我的值一直为 0。我尝试移动原始变量以更改范围,到目前为止没有任何帮助。

const staffTotalPrices = (eventFirebaseKey) => new Promise((resolve, reject) => {
  eventStaff.getEventStaff(eventFirebaseKey).then((staffArray) => {
    let staffTotal = 0;
    staffArray.forEach((staff) => {
      staffData.getSingleStaff(staff.staffUid).then((staffObject) => {
        staffTotal += parseInt(staffObject.price, 10);
        return staffTotal;
      });
    });
    resolve(staffTotal);
  }).catch((error) => reject(error));
});

我一直把它推到一个空数组,然后做一个 .reduce 数组方法来添加总数,但是我不得不在调用它/减少它时设置一个超时只是为了等待 API 响应

标签: javascriptscopees6-promise

解决方案


在您的forEach循环中,您正在调用异步函数但不等待其结果。所以你resolve(staffTotal)在任何staffData.getSingleStaff解决之前打电话。

例如,您可以执行一个 Promise.all()将执行所有承诺并使用结果数组进行解析的操作。

const staffTotalPrices = (eventFirebaseKey) => new Promise((resolve, reject) => {
  eventStaff.getEventStaff(eventFirebaseKey)
    //execute getSingleStaff for all elements in the array and resolve when all are resolved
    .then(staffArray => Promise.all(staffArray.map(staff => staffData.getSingleStaff(staff.staffUid))))
    //sum up the prices in the staffObjects array with reduce
    .then(staffObjects => staffObjects.reduce((a,c) => parseInt(a.price, 10) + parseInt(c.price, 10), 0))
    //resolve the promise with the sum
    .then(totalStaff => resolve(totalStaff));
    .catch((error) => reject(error));
});

另一种可能性是,在 forEach 循环中保留已解决的承诺计数。并且一旦所有的承诺都解决了,也解决了外部的承诺。但是当然,您还需要捕获内部 Promise 的拒绝,否则如果其中一个拒绝您的 Promise,您的 Promise 可能会停留在待处理状态。

const staffTotalPrices = (eventFirebaseKey) => new Promise((resolve, reject) => {
  eventStaff.getEventStaff(eventFirebaseKey).then((staffArray) => {
    let staffTotal = 0; let resolveCounter = 0;
    staffArray.forEach((staff) => {
      staffData.getSingleStaff(staff.staffUid)
        .then((staffObject) => {
          staffTotal += parseInt(staffObject.price, 10);
          if (++resolveCounter == staffArray.length) 
            resolve(staffTotal);
        })
        .catch(e => reject(e));
    });
  }).catch((error) => reject(error));
});

推荐阅读