异步减少回报承诺

时间:2019-08-14 19:49:20

标签: javascript node.js ecmascript-6 reduce

我有一个对象数组,我必须在每个来自和异步函数的对象上添加一个属性

我正在执行Array.reduce来迭代每个元素并仅返回一个结果:一个具有new属性的对象数组。

我有这个

const res = await resultOne.reduce(async (users = [], user, i) => {
          let userName;
          try {
            let { name } = await names.getNames(user.id);
            userName = name;
          } catch (error) {
            throw error;
          }
          delete user.id;
          users.push({ ...user, userName });
          return users;
      }, []);

但是我收到消息了

  

推送不是用户的功能

这是因为我认为这是一个承诺。

如何处理reducemap中的异步请求

2 个答案:

答案 0 :(得分:4)

是的,users是一个承诺。请勿将reduceasync函数一起使用。您可以在第一行中执行类似await users的操作,但这将是非常低效的并且很简单。

使用普通循环:

const users = [];
for (const user of resultOne) {
    const { name } = await names.getNames(user.id);
    delete user.id;
    users.push({ ...user, userName: user });
}

,或者在您可以同时进行所有操作和创建数组的情况下,将map函数与Promise.all一起使用:

const users = await Promise.all(resultOne.map(async user => {
    const { name } = await names.getNames(user.id);
    delete user.id;
    return { ...user, userName: user };
}));

答案 1 :(得分:0)

因为它是一个异步函数,所以每次您返回某些内容时,它都会被包装在promise中。要解决此问题,您需要将起始数组设置为promise,然后在每次迭代中等待累加器。

const res = await resultOne.reduce(async (users, user, i) => {
  try {
    return [
      ...await users,
      { ...user, userName: await names.getNames(user.id.name) }
    ]
  } catch (error) {
    console.log(error)
  }
}, Promise.resolve([]));