我有这个小程序,通过乘以一个小时和一些小时来计算总数。
我遇到的问题是函数getTasks()总是返回一个空映射。 当我记录在地图中输入的字段时,它们不是空的,但是在函数返回地图后输入它们。 所以我有点困惑为什么会发生这种情况。
function getTask(taskId) {
return rp({
uri: `${url}/tasks/${taskId}`,
auth: {
user: 'user',
password,
sendImmediately: false
},
json: true
}).then((task) => {
return task;
});
}
function getTasks(entries) {
const taskIds = [];
entries.forEach((entry) => {
const taskId = entry.day_entry.task_id;
if (!taskIds.includes(taskId)) {
taskIds.push(taskId);
}
});
const taskRateMap = new Map();
taskIds.forEach((taskId) => {
return Promise.resolve(getTask(taskId)).then((res) => {
if (res.task.id === taskId) {
taskRateMap.set(taskId, res.task.default_hourly_rate);
console.log(taskRateMap);
}
});
});
return taskRateMap;
}
function calculateTasksTotals(id) {
return co(function* calculateTotalsGen() {
let total = 0;
const entries = yield getEntriesForProject(id);
const tasks = getTasks(entries);
entries.forEach((entry) => {
const rate = tasks.get(entry.day_entry.task_id);
total += rate * entry.day_entry.hours;
});
return total;
});
}
calculateTasksTotals(id)
答案 0 :(得分:0)
您的承诺存在问题。尝试使用Promise.all()
提供所有承诺作为输入,并仅在所有承诺都已解决后返回您的地图。
否则直接返回你的Promise.all()并在调用方法中创建地图。
类似于:
const tasksPromises = [];
taskIds.forEach((taskId) => {
tasksPromises.push(getTask(taskId));
});
return Promise.all(tasksPromises);
然后在你的调用方法中通过then
解析promises,你将把回调函数的参数作为一个数组,其中每个元素都是相应promise的返回值。
答案 1 :(得分:0)
我相信这种情况正在发生,因为taskRateMap在返回之前没有被填充。您可能想要查看Promise.all() 并考虑包装
promises = taskIds.map((taskId) => {
return Promise.resolve(getTask(taskId)).then((res) => {
if (res.task.id === taskId) {
return [taskId, res.task.default_hourly_rate];
console.log(taskRateMap);
}
});
return Promise.all(promises).then(v => /* taskRateMap*/)
答案 2 :(得分:0)
您的代码存在多个问题:
首先,只要您在函数中涉及任何异步操作,该函数的结果将是异步的。你根本无法同步返回它。异步操作稍后完成。函数本身在异步操作完成之前返回。
因此,您从使用异步操作的任何函数返回一个promise,并且调用者使用该promise来知道事情何时完成或获得最终结果。
您的函数getTask()
没问题。它返回一个承诺。该函数内的.then()
是多余的,不需要,因为task
似乎已经是承诺的已解析值。
您的函数getTasks()
正在尝试同步返回taskRateMap
,但正如您在测试中看到的那样,所有承诺都没有得到解决,因此{{1}中没有值尚未。在我的代码版本中,我在内部使用taskRateMap
来了解所有Promise.all()
操作何时完成,并且我返回一个已解析值为getTask()
对象的承诺。
taskRateMap
的调用者可以使用该承诺和getTasks()
处理程序来访问.then()
对象。
这是实现taskRateMap
的一种方式:
getTasks()