javascript - 当我试图在一个承诺内计算一个价格时返回一个零值
问题描述
我试图从 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 响应
解决方案
在您的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));
});
推荐阅读
- python - 组和通道层使流程停止而不会引发异常
- c# - 如何使用 android.hardware.usb 和 c# 使用 jni 读取 Unity 2018 android 应用程序中的 USB 存储?
- docker - 强制构建特定的 Docker 层
- rust - 有没有办法让结构包含可能不再有效的引用?
- javascript - Javascript将字符串拆分为多维数组
- r - 将单行文件读入 R
- javascript - 单击 X 时关闭菜单
- stackexchange.redis - StackExchange.redis - Redis 批处理超时
- python - 可以使用 subprocess.Popen for python3.7 处理命令列表
- django - 我如何将 html 复选框值保存到 django 数据库