【问题标题】:async await with promise all异步等待所有承诺
【发布时间】:2020-03-26 07:36:06
【问题描述】:

我想知道我是否在异步等待中正确使用了 promise.all。

基本上,我需要根据 ID 获取房屋数据,然后我需要获取该房屋的所有评论以及评论计数。

  server.get("/api/houses/:id", async (req, res) => {
    const { id } = req.params;
    const house = await House.findByPk(id);
    if (!house) {
      return res.status(400).send("No house found");
    }

    const reviews = await Review.findAndCountAll({
      where: {
        houseId: house.id
      }
    });

    house.dataValues.reviewsCount = reviews.count;

    const results = await Promise.all([house.dataValues, reviews.rows]);
    console.log(results);
    res.send(results);
  });

在前端,当我在发出 http 请求后 console.log 响应时,我会返回下面的内容,这似乎没问题,因为 Promise.all 为您提供了数组。但我不知道这是否是最好的方法,或者是否有更好的方法。

[
  {
    id: 2329,
    host: 2,
    picture: '/img/houses/1.jpg',
    type: 'Entire house',
    town: 'Some town',
    title: 'Some title',
    price: 50,
    description: 'Some description',
    guests: 4,
    bedrooms: 1,
    beds: 2,
    baths: 1,
    wifi: true,
    reviewsCount: 2
  },
  [
    {
      id: 1,
      houseId: 2329,
      userId: 1,
      comment: 'An awesome review',
      createdAt: '2019-01-11T22:00:00.000Z',
      updatedAt: '2019-01-11T22:00:00.000Z'
    },
    {
      id: 2,
      houseId: 2329,
      userId: 2,
      comment: 'Another awesome review',
      createdAt: '2019-01-11T22:00:00.000Z',
      updatedAt: '2019-01-11T22:00:00.000Z'
    }
  ]
]

【问题讨论】:

    标签: node.js async-await sequelize.js


    【解决方案1】:

    您可以忽略async await 并使用Promise。你可以试试下面的代码

    server.get("/api/houses/:id", async (req, res) => {
       const { id } = req.params;
    
       return House.findByPk(id)
         .then( house => {
            // !house might be 'true' if house is 'undefined'
            if( house === undefined || !house ) {
               return res.status(400).send("No house found");
            }
    
            return Review.findAndCountAll({ where: {  houseId: house.id } })
               .then(reviews => {
                  house.dataValues.reviewsCount = reviews.count;
                  return {house, reviews};
               })
               .catch(error => res.send(error));
          })
          .then( result => {
             return res.send(results);
          })
          .catch(error => {
              return res.send(error);
          });
       })
    

    【讨论】:

    • 谢谢,但我想使用 async/await
    【解决方案2】:

    您没有正确使用Promise.all。该代码正在运行,因为您正在 awaiting 每个承诺单独。

    由于Review.findAndCountAll 依赖于House.findByPk 结果,Promise.all 在这里不会有任何好处。

    您正在使用 Promise.all 和两个 Promise 的已解析值,因此您可以放弃它。

     server.get("/api/houses/:id", async (req, res) => {
        const { id } = req.params;
        const housePromise = await House.findByPk(id);
    
    
        const reviews = await Review.findAndCountAll({
          where: {
            houseId: house.id
          }
        });
    
        house.dataValues.reviewsCount = reviews.count;
    
        res.send([house.dataValues, reviews.rows]);
     });
    

    基本上你在做:

    const res = await Promise.all([1, 5]); // [1, 5]
    

    可以直接翻译成:

    const res = [1, 5];
    

    与其在数组中发送,我认为发送对象更好:

    {
       house: house.dataValues,
       reviews: reviews.rows
    }
    

    【讨论】:

    • 啊,好吧。谢谢!它仍然以数组的形式发回数据,所以说要获取house.dataValues 我会使用props.house[0].title 和评论props.house[1].comment 是否正确
    • 是的,当我把它放在前端时看起来确实好多了!
    猜你喜欢
    • 2017-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-03
    • 2018-03-05
    • 1970-01-01
    • 2018-12-24
    • 2023-04-06
    相关资源
    最近更新 更多