【问题标题】:try / catch vs then() / catch() for [err, result] = await promisetry / catch vs then() / catch() for [err, result] = await promise
【发布时间】:2019-04-06 22:48:27
【问题描述】:

这可能是重复的,但我还没有找到答案。

我希望表达式 let result = await promise; 返回 Node.js 样式 [err, result] 的结果。

有两种解决方案。由于我对 Node.js/then()/catch()/async/await 不太熟悉,所以我想知道每种方法的优缺点。

第一(https://www.npmjs.com/package/await-to-js):

我在这里找到它:https://blog.grossman.io/how-to-write-async-await-without-try-catch-blocks-in-javascript

function to(promise) {
   return promise.then(data => {
      return [null, data];
   })
   .catch(err => [err]);
}

第二:

async function to2(promise) {
  try {
    return [null, await promise];
  } catch (e) {
    return [e];
  }
}

两者的调用方式相同:let [err, user] = await to/to2(User.create(...));

【问题讨论】:

    标签: node.js async-await try-catch


    【解决方案1】:

    编辑 2020:

    这就是我现在的工作方式。我为此使用了辅助函数,而不是库。

    //helpers.js
    
    export function until(promiseOrPromiseList) {
      if (!promiseOrPromiseList) {
        console.error("no promise passed.",promiseOrPromiseList);
        return Promise.reject(["Unknown Error"]);
      }
      //array of promises
      if (Array.isArray(promiseOrPromiseList)) {
        return Promise.all(promiseOrPromiseList)
          .then((data) => {
            return [null, data];
          })
          .catch((err) => {
            return [err, promiseOrPromiseList.map((p) => undefined)];
          });
      }
      //single promise call
      return promiseOrPromiseList
        .then((data) => {
          // console.log(data);
          return [null, data];
        })
        .catch((err) => {
          // console.log(err)
          return [err];
        });
    }
    

    我的用法是-

    import {until} from "../helpers.js";
    
    async function sendUserDetails() {
        const [err, user] = await until(getUserFromDb(userId));
        if (err) {
          errorLog.error(err);
          return res.json({success:false,msg:"An Error occured"})
        }
        res.json({success:true,user:user})
       }
    
    

    因此,您只需将返回 Promise 的函数包装在 until 中,并将其分配给元组(此处为两个项目的数组)以获取 errresult(视情况而定)。

    旧答案:

    我认为您不需要使用任何库来编写可读的、具有同步外观的异步代码。 我一直在使用没有 try/catch 块的 async-await,方法如下 -

    //write a promise
    function getUserFromDb(userId){
        return new Promise((resolve,reject)=>{
           if(userId == undefined){
              return reject('no userId specified');//return to stop proceeding further.
           }
           UserModel.findById(userId,function(err,user){
              if(err) return reject('error while fetching user details.')
              resolve(user);
        });
    }
    //-------------------
    
    //usage
    //remember to use async keyword before function declaration
    //... 
    
    let user = await getUserFromDb(userId).catch(err=>console.log(err));
    
    //user will be undefined, if the promise was rejected.
    if(!user){
       console.log('error while getting the details');
    }
    //...
    

    或者,如果您想专门使用错误,

    //usage
    let user,userErr;
    user = await getUserFromDb(userId).catch(err=>userErr = err);
    if(!user){
    console.log(userErr);
    }
    

    使用额外的一行,您可以避免使用外部库并将代码包装在不必要的函数中。

    但如果您必须使用其中一个 sn-ps,那么第一个会好得多,因为 try/catch 块会降低性能。

    【讨论】:

    • 是的,但必须附加 .catch(err=>userErr = err) 是我想要摆脱的
    • 嗯,我从来不觉得这是个问题,而且我还没有找到适合我的更短的版本。很想知道。考虑到 promise 的嵌套和库的包装函数,以如此短的成本使用该语言的本机特性实际上感觉很好。但是,如果您习惯使用微型库并喜欢漂亮的语法,那就太好了。
    猜你喜欢
    • 2020-01-02
    • 2019-11-15
    • 1970-01-01
    • 2017-07-27
    • 1970-01-01
    • 2017-06-08
    • 2015-09-30
    • 2016-10-18
    • 2012-09-07
    相关资源
    最近更新 更多