首页 > 解决方案 > 这是使用承诺时打破“THEN 链”的好方法吗?

问题描述

我有一个简单的“然后链”运行一些功能步骤。如果满足某些条件,我需要取消链并退出(主要是发生错误时)。我在firebase云功能中使用它,但我认为这是适用于任何节点/快速环境的基本概念。

这是我的代码:

let p1 = db.collection('products').doc(productId).get();
let p2 = db.collection('user_data').doc(userUid).get();
let promises= [p1,p2];

return Promise.all(promises)
    .then(values => 
    {
        let proudctDoc = values[0];
        let userDataDoc = values[1];

        if(!proudctDoc.exists)
        {
            console.log("The product does not exist");
            response.status(404).json({error: ErrorCodes.UNKNOWN_PRODUCT, msg: "The products does not exist"});
            throw("CANCEL");
        }

        if(!userDataDoc.exists)
        {
            console.log("User data block not found!");
            response.status(404).json({error: ErrorCodes.UNKNOWN_USER_DATA, msg: "User data block not found!"});   
            throw("CANCEL");
        }

        variantCountryRef = db.doc('products/'+productId+'/variants/'+variantCountry);
        return variantCountryRef.get();
    })
.then(variantCountryDoc =>
{
    ....
})
.catch(err =>
{
    if(err !== "CANCEL")
    {
        //Deal with real error
    }
}      

如您所见,我只运行 2 个 Promise 并等待它们完成。在此之后,我检查一些返回值并在发生错误时通知客户端。这时我必须完成“然后链”。

这是一种常见的模式吗?有什么我可以改进的吗?

标签: javascriptnode.js

解决方案


您可以执行以下操作:

  const p1 = db.collection('products').doc(productId).get();
  const p2 = db.collection('user_data').doc(userUid).get();
  const promises = [p1, p2];

  return Promise.all(promises)
    .then(values => {
      let proudctDoc = values[0];
      let userDataDoc = values[1];

      if (!proudctDoc.exists) {
        console.log('The product does not exist');
        throw new Error(ErrorCodes.UNKNOWN_PRODUCT);
      }

      if (!userDataDoc.exists) {
        console.log('User data block not found!');
        throw new Error(ErrorCodes.UNKNOWN_USER_DATA);
      }

      variantCountryRef = db.doc(
        'products/' + productId + '/variants/' + variantCountry
      );
      return variantCountryRef.get();
    })
    .then(variantCountryDoc => {
         //Don't forget to send a response back to the client, see https://www.youtube.com/watch?v=7IkUgCLr5oA&
         //...
         //response.send(...);
    })
    .catch(err => {
      if (err.message === ErrorCodes.UNKNOWN_PRODUCT) {
        response.status(404).json({
          error: ErrorCodes.UNKNOWN_PRODUCT,
          msg: 'The products does not exist'
        });
      } else if (err.message === ErrorCodes.UNKNOWN_USER_DATA) {
        response
          .status(404)
          .json({
            error: ErrorCodes.UNKNOWN_USER_DATA,
            msg: 'User data block not found!'
          });
      } else {
        //Deal with other error types
      }
    });

推荐阅读