Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/40.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
承诺无法在reduce数组方法javascript中得到解决_Javascript_Node.js_Ecmascript 6_Async Await - Fatal编程技术网

承诺无法在reduce数组方法javascript中得到解决

承诺无法在reduce数组方法javascript中得到解决,javascript,node.js,ecmascript-6,async-await,Javascript,Node.js,Ecmascript 6,Async Await,我有大量的对象,并根据用户ID过滤对象。下面是代码 const filteredArr = LargeArr.Items.reduce( async(acc, { attributes: { dob, name, picture} = { dob: null, name: null, picture: null }, userID }) => { let pic = null; if (picture)

我有大量的对象,并根据用户ID过滤对象。下面是代码

const filteredArr = LargeArr.Items.reduce(
            async(acc, { attributes: { dob, name, picture} = { dob: null, name: null, picture: null }, userID }) => {
                let pic = null;
                if (picture) { pic = await getPic(picture); } // async here
                acc[userID] = { name, userID, pic, dob };
                return acc;
            }, {});
预期产出:

{
  '1595232114269': {
    name: 'Mark Status',
    userID: '1595232114269',
    picture: 'mark-status.jpg',
    dob: '2020-08-10'
  },
  '48e69555d778f9b9a3a1d553b9c3b8f7dd6a3394ac82df1433b60a69c055d23d': {
    name: 'Jack Thomas',
    userID: '48e69555d778f9b9a3a1d553b9c3b8f7dd6a3394ac82df1433b60a69c055d23d',
    picture: 'jack-thomas.jpg',
    dob: '1990-12-20'
  },
  '48e69555d778f9b9a3a1d553b9c3b8f7dd6a3394ac82df1433b60a69c055d47p': {
    name: 'Petro Huge',
    userID: '48e69555d778f9b9a3a1d553b9c3b8f7dd6a3394ac82df1433b60a69c055d47p',
    picture: 'petro huge.jpg',
    dob: '1856-12-20'
  },
  '48e69555d778f9b9a3a1d553b9c3b8f7dd6a3394ac82df1433b60a69c055d55j': {
    name: 'Mark Henry',
    userID: '48e69555d778f9b9a3a1d553b9c3b8f7dd6a3394ac82df1433b60a69c055d55j',
    picture: 'mark-henry.jpg',
    dob: '2005-12-29'
  }
}
我需要从一个异步的api获取图片,所以在reduce方法中使用了async wait。这里的问题是,它总是表现为承诺待定。如果这是一个对象数组,那么我可以返回Promise.all,但既然这是一个包含对象的对象,我如何继续使用这个内部reduce方法呢?我需要完全相同的预期输出


有人能帮我吗?非常感谢您的帮助。

要在异步迭代项时使用
reduce
,您必须将从一个回调传递到另一个回调的累加器作为承诺。虽然这是可能的,但它会使阅读变得非常困难,并引入一些不必要的语法干扰

对于循环,请使用普通的

const filteredArr = {};
for (const item of LargeArr.Items) {
  const { attributes: { dob, name, picture} = { dob: null, name: null, picture: null } } = item;
  const pic = picture ? await getPic(picture) : null;
  filteredArr[userID] = { name, uesrID, pic, dob };
}
如果您真的想走
reduce
路线:

LargeArr.Items.reduce(
  (acc, { attributes: { dob, name, picture} = { dob: null, name: null, picture: null }, userID }) => {
    return acc.then(async (acc) => {
      let pic = null;
      if (picture) { pic = await getPic(picture); } // async here
      acc[userID] = { name, userID, pic, dob };
      return acc;
    });
  }, Promise.resolve({})
)
  .then((filteredArr) => {
    // do stuff with filteredArr
  });

除非在串行中需要调用<代码> GETPIC调用,否则您可以考虑使用<代码>承诺>所有,而不是一次迭代整个数组,而不是等待下一个承诺的解析,然后再进入下一个。 如果您的API能够处理

承诺。所有

const filteredArr = {};
await Promise.all(LargeArr.Items.map(async (item) => {
  const { attributes: { dob, name, picture} = { dob: null, name: null, picture: null } } = item;
  const pic = picture ? await getPic(picture) : null;
  filteredArr[userID] = { name, uesrID, pic, dob };
}));

acc
将在第一次迭代后成为一个承诺(因为
async
函数返回一个承诺)。当变量
filteredar
的内容是对象时,为什么变量的名称是?名称表明它存储了一个
Array.prototype.filter()
调用的结果。@FelixKling是的,你能告诉我怎么做吗?你可以使用Promise.all()首先进行所有必要的API调用,然后在后面使用
.reduce
并传递一个同步函数。只是不要在这里使用
reduce
),这会使事情变得不必要的复杂。第二个示例不起作用,因为
acc
在第一次迭代中不是一个承诺。但是如果你做了
acc=等待acc
而不是
返回acc.then(…)
(并使外部函数
异步
),那么它应该可以工作。@对于常量属性的分解,内部的某些性能,我认为缺少一个大括号,对吗?@Vishnu是的,修复了它。嵌套的解构使读写变得困难,可能需要在possible@CertainPerformance我不明白你的观点,getPic的电话是串行的,使用Promise.all。如果你能解释一下就好了。谢谢。@Vishnu说
getPic
需要1秒。然后,如果阵列中有5张图片,您当前的方法和
总共需要5秒。但是如果您使用
Promise.all
,您可以一次发送所有请求,因此总共只需要1秒。但是如果
getPic
需要串行运行(一个接一个),那么请坚持使用
for
循环,而不是
Promise.all