【问题标题】:How to return the result of multiple promises in an express route?如何在快速路由中返回多个承诺的结果?
【发布时间】:2018-08-02 08:30:04
【问题描述】:

以下是为我的用户仪表板检索信息的路线。我试图避免嵌套所有的承诺(我听说它叫做回调地狱)并且仍然得到正确的结果。我假设下面的代码 sn-p 没有返回任何内容,因为在运行时它会吹过所有的承诺,只是在承诺有机会解决之前返回三个空数组。我尝试使用 async/await 没有成功,我不确定这是否是我需要的。在这种给定的情况下,处理这些承诺并一次返回所有结果的最佳实践是什么?

// @route 	GET api/user/dashboard
// @desc	Retrieve all of the user's dashboard info
// @access	Private
router.get("/dashboard",
  passport.authenticate("jwt", { session: false }),
  (req, res) => {
    const donations = [];
    const events = [];
    const teams = [];

    req.user.donations.forEach(donation_id => {
      Donation.findOne({ _id: donation_id })
        .then(donation => {
          if (donation) {
            donations.push(donation);
          }
        })
        .catch(err => console.log(err));
    });

    req.user.events.forEach(event_id => {
      Event.findOne({ _id: event_id })
        .then(event => {
          if (event) {
            events.push(event);
          }
        })
        .catch(err => console.log(err));
    });

    req.user.teams.forEach(team_id => {
      Team.findOne({ _id: team_id })
        .then(team => {
          if (team) {
            teams.push(team);
          }
        })
        .catch(err => console.log(err));
    });

    return res.status(200).json({ data: { donations, events, teams } });
  }
);

【问题讨论】:

    标签: node.js express


    【解决方案1】:

    使用Promise.all 等待所有Promises 首先解决。您需要将每个donation(和event,和team)映射到Promise,这样您就可以在每组Promises 上调用Promise.all,然后您需要调用@987654329 @这三个组。

    因为donationseventsteams 都需要类似的东西(从数组中提取_id 属性,用_id 调用.findOne,并过滤所有结果),它会最好将所有内容抽象为一个函数,以保持代码干燥:

    const getItems = async (arr, finder) => {
      const foundItems = await Promise.all(
        arr.map(({ _id }) => finder.findOne({ _id }))
      );
      return foundItems.filter(Boolean);
    };
    
    async (req, res) => {
      const [donations, events, teams] = await Promise.all([
        getItems(req.user.donations, Donation),
        getItems(req.user.events, Event),
        getItems(req.user.teams, Team),
      ])
        .catch(err => console.log(err));
      return res.status(200).json({ data: { donations, events, teams } });
    };
    

    没有asyncawait

    const getItems = (arr, finder) => (
      Promise.all(
        arr.map(({ _id }) => finder.findOne({ _id }))
      )
      .then((foundItems) => foundItems.filter(Boolean))
    );
    
    (req, res) => {
      Promise.all([
        getItems(req.user.donations, Donation),
        getItems(req.user.events, Event),
        getItems(req.user.teams, Team),
      ])
        .then(([donations, events, teams]) => {
          res.status(200).json({ data: { donations, events, teams } });
        })
        .catch(err => console.log(err));
    };
    

    【讨论】:

    • 谢谢大佬,说的很详细。我是否需要运行特定版本的节点来解析 async (req, res) => { ?我之前尝试过,但口译员抱怨。
    • 我相信你需要 Node 7.6+ 才能使用awaitawait 让程序流程更容易理解,但不是必须的,没有async/await的代码见编辑
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-16
    • 2017-09-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多