promise.all 不返回实际结果

Posted

技术标签:

【中文标题】promise.all 不返回实际结果【英文标题】:promise.all doesn't return actual results 【发布时间】:2019-09-26 08:54:44 【问题描述】:

我有这个代码:

  let result = programBenef.map(async item => 
    const beneficiary = await Beneficiary.findById(item.beneficiary_id);
    delete item.beneficiary_id;
    return 
      ...item,
      ...beneficiary
    ;
  );

  result = await Promise.all(result);

console.log(result);

当我执行 console.log(result) 时,我得到了这个结果:

  Promise 
     '$__': [InternalCache],
      isNew: false,
      errors: undefined,
      _doc: [Object],
      '$init': true  ,
  Promise 
     '$__': [InternalCache],
      isNew: false,
      errors: undefined,
      _doc: [Object],
      '$init': true  

为什么不返回实际结果,如何解决?

编辑 1: 这是整个功能:

router.get("/getProgramDistr/:id", auth, async (req, res) => 
  if (req.user.roles === 1) return res.status(403);
  if (!req.params.id) return res.status(400);

  const admin_id = req.user.father_id || req.user._id;
  const programDistr = await ProgramDistributor.find(
    admin_id,
    program_id: req.params.id
  );
  if (!programDistr) return res.status(404);

  let result = await programDistr.map(async item => 
    const beneficiary = await Distributor.findById(item.distributor_id);
    delete item.distributor_id;
    return 
      ...item,
      ...beneficiary
    ;
  );

  result = await Promise.all(result);

  // console.log(result, "this is the result");

  return res.send(result);
);

我尝试使用 for loop 代替 map 并将 promise 推送到一个数组,然后调用 Promise.all(array) 仍然是相同的结果。

【问题讨论】:

你在哪里调用这个函数?请同时显示包装功能。 我已经用整个功能更新了帖子 看起来您正在记录result 之前 等待并分配Promise.all 调用的结果。我建议对 promise 数组和标识符数组使用两个不同的变量,以确保你没有搞砸。 顺便说一句,programDistr.map(…) 返回的数组上的await 完全是多余的,你应该放弃它。 (但它不应该造成任何伤害,比如导致您声称获得的奇怪日志)。 如果我理解你的话,我已经从 programDistr.map(...) 前面删除了 await 并将 Promise.all() 的结果分配给另一个变量并记录了该变量但还是同样的问题@Bergi 【参考方案1】:

这可能是您正在寻找的解决方案

const promises = programDistr.map(async item => Distributor.findById(item.beneficiary_id).lean() );

const results = await Promise.all(promises);

return res.send(results);

细分


programDistr.map(async item => Distributor.findById(item.beneficiary_id).lean() ); 这将返回一组承诺,这些承诺将使用匹配的 beneficiary_id 查询数据库中的分销商。lean() 是一个只返回原始文档的猫鼬查询(我相信你要去for and 将省略您对map 的最后一次调用_doc 对象)。 mongoose lean documentation

await Promise.all(promises) 等待所有查询完成并返回到results 变量。

【讨论】:

【参考方案2】:

为了解决这个问题,我把代码改成了这样:

  const result = programDistr.map(async item => 
    const distributor = await Distributor.findById(item.beneficiary_id);
    delete item.beneficiary_id;
    return 
      ...item,
      ...distributor
    ;
  );

  const outcome = await Promise.all(result);

  let resss = outcome.map(item => 
    return item._doc;
  );

  return res.send(resss);

结果仍然给我一个看起来很奇怪的数组,每个数组的索引中都有一个对象,但是当遍历数组并获取 item._doc 的键的值时,我找到了实际结果。

但是,为什么 promise.all() 不能返回实际结果呢?

【讨论】:

我在下面的回答描述了您面临的问题。 Mongoose 有一个名为lean 的内置方法可以解决这个问题:) mongoosejs.com/docs/tutorials/lean.html

以上是关于promise.all 不返回实际结果的主要内容,如果未能解决你的问题,请参考以下文章

es6 promise.all()

Promise.all()使用方法

如何返回 Promise.all 获取 api json 数据?

[万字详解]JavaScript 中的异步模式及 Promise 使用

Promise.All不等待Promise解决

实现promise.all方法