Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 异步减少返回承诺_Javascript_Node.js_Ecmascript 6_Reduce - Fatal编程技术网

Javascript 异步减少返回承诺

Javascript 异步减少返回承诺,javascript,node.js,ecmascript-6,reduce,Javascript,Node.js,Ecmascript 6,Reduce,我有一个对象数组,我必须在来自和异步函数的每个对象上添加一个属性 我正在做一个Array.reduce来迭代每个元素并只返回一个结果:一个具有新属性的对象数组 我有这个 const res = await resultOne.reduce(async (users = [], user, i) => { let userName; try { let { name } = await names.getNames(user.i

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

我正在做一个Array.reduce来迭代每个元素并只返回一个结果:一个具有新属性的对象数组

我有这个

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;
      }, []);
但我明白了

推送不是用户的功能

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


我如何处理
reduce
map

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

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([]));

是的,
用户
是一种承诺。不要将
reduce
async
函数一起使用。您可以在第一行中执行类似于等待用户的
,但这将是非常低效和单调的

使用普通循环:

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 };
}));

wait
ing
用户
之后(在
wait
ing
getNames()
之后)将导致未经处理的拒绝警告如果其中一个承诺失败,请参阅或@Bergi I刚刚更新了我的答案。这会阻止/修复您正在谈论的内容吗?是的,它们现在将按顺序执行。尽管如此,我还是不认为这是一个好的解决方案,它令人困惑且容易搞乱:-)谢谢@JossClassey的回复,我一直在遵循这种解决方案,但我也同意这不是一个更具可读性的选择。如果你能使用Promise库,你可以使用bluebird的Promise.reduce。例如,
const res=wait Promise.reduce(resultOne,async(用户…
@Paulpro感谢您的回复,问题是我不认为在这种情况下添加另一个依赖项是完全必要的,这是我不会在整个项目中重复的。感谢您的回复@Bergi,我认为普通循环可以很好地工作,并且更具可读性,可以使用我将通过数千个循环。但是我认为没有办法避免运行所有的循环来删除user.id并添加user.name