异步等待所有承诺

Posted

技术标签:

【中文标题】异步等待所有承诺【英文标题】: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'
    
  ]
]

【问题讨论】:

【参考方案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 是否正确 是的,当我把它放在前端时看起来确实好多了!

以上是关于异步等待所有承诺的主要内容,如果未能解决你的问题,请参考以下文章

异步函数 - 等待不等待承诺

异步等待承诺上的 UnhandledPromiseRejectionWarning

在自定义承诺上使用异步等待

在自定义承诺上使用异步等待

在异步/等待中包装承诺

Javascript - 异步等待和获取 - 返回值,而不是承诺?