如何在Javascript中将异步API调用作为值构建对象

如何在Javascript中将异步API调用作为值构建对象,javascript,asynchronous,javascript-objects,Javascript,Asynchronous,Javascript Objects,再一次,异步性让我大吃一惊。 问题:我有一个配置文件,我必须根据该文件构建多级对象,例如: export const personnelTasks = { manager: { administrative: ['meetings', 'evaluation', 'time-reporting', 'vacation-approval'], operational: ['budgeting', 'supervising', 'customer-complaints'] }

再一次,异步性让我大吃一惊。 问题:我有一个配置文件,我必须根据该文件构建多级对象,例如:

export const personnelTasks = {
  manager: {
    administrative: ['meetings', 'evaluation', 'time-reporting', 'vacation-approval'],
    operational: ['budgeting', 'supervising', 'customer-complaints']
  },
  frontDesk: {
    administrative: ['time-tracking', 'file-reports', 'cash-reporting', 'take_on', 'dribble'],
    operational: ['answer-calls', 'face-to-face-meetings', 'cash-counting', 'process-requests']
  }
};
因此,根据员工是经理还是前台员工,我将有一份包含两个选项卡的报告,
管理
操作
,以及他们必须执行的各种任务。对于其中的每一个,后端返回一系列数据,但从不同的API端点提供服务。例如,对于会议,我有一个API端点
{DEV_API}/meetings

我要做的是一次调用所有API端点,并为每种类型的员工构建一个对象,如下所示:

const timeTrackingData = {
  administrative: {
    meetings: {...}
    evaluation: {...}
    .....
  },
  operational: {
    budgeting: {...},
    supervising: {...}
    .....
  }
}
我的解决方案是使用配置对象并基于它构建新对象,对于每个键,使用异步/等待调用调用API

getTimeTrackingData (employeeID, employeeType) {
    const timeTrackingDataObject = {};
    Object.keys(personnelTasks[employeeType]).forEach((taskCategory) => {
      timeTrackingDataObject[taskCategory] = {};
      personnelTasks[employeeType][taskCategory].forEach(async (task) => {
        timeTrackingDataObject[taskCategory][task] = {};
        timeTrackingDataObject[taskCategory][task] = await axios.get(`${DEV_API}/employees/${employeeId}/time-tracking/${task}`);
      });
    });

    return timeTrackingDataObject;
  },
因此,当我访问
timeTrackingObject
时,我可以看到对象的第一级,但在下面我可以看到我无法访问的可观察对象。此外,我严重怀疑
forEach
循环和
async/await
是否是一条可行之路,但我只想现在就解决这个问题,然后再考虑更好/更高效的实现。

一种方法是:

Object.keys(personnelTasks[employeeType]).map(
    taskCategory => personnelTasks[employeeType][taskCategory].map(
        task => axios.get(`${DEV_API}/employees/${employeeId}/time-tracking/${task}`)
    )
)
您有一个二维数组,其中包含未解析的承诺。
您必须使用
promise.all处理此数组,然后构建对象。

getTimeTrackingData
从同步方法返回。但是,这种方法包含异步操作。我建议您使用一种依赖于
Promise的方法。所有
和返回
timeTrackingDataObject
仅在每个Promise都得到解决后。是的,我考虑过这个选项,但我还需要构建对象结构。您认为这需要在
承诺后完成吗?所有
都解决了吗?不,代码可以保持原样,不需要移动对象声明。只需构建一个promise数组并使用
promise.all
;一切都应按预期进行。