正确的 Try...Catch 语法使用 Async/Await [英] Correct Try...Catch Syntax Using Async/Await

查看:104
本文介绍了正确的 Try...Catch 语法使用 Async/Await的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我喜欢 Typescript 等中可用的新 Async/Await 功能的扁平化.但是,我不确定我是否喜欢这样一个事实,即我必须声明变量 Im awaittry...catch 块的外部,以便稍后使用它.像这样:

I like the flatness of the new Async/Await feature available in Typescript, etc. However, I'm not sure I like the fact that I have to declare the variable I'm awaiting on the outside of a try...catch block in order to use it later. Like so:

let createdUser
try {
    createdUser = await this.User.create(userInfo)
} catch (error) {
    console.error(error)
}

console.log(createdUser)
// business
// logic
// goes
// here

如果我错了,请纠正我,但最好的做法是不要try 主体中放置多行业务逻辑,所以我剩下的唯一选择是在块外声明 createdUser,在块中分配它,然后在之后使用它.

Please correct me if I'm wrong, but it seems to be best practice not to place multiple lines of business logic in the try body, so I'm left only with the alternative of declaring createdUser outside the block, assigning it in the block, and then using it after.

这种情况下的最佳实践是什么?

What is best practice in this instance?

推荐答案

最好的做法是不要在 try 主体中放置多行业务逻辑

It seems to be best practice not to place multiple lines of business logic in the try body

实际上我会说是的.您通常希望在使用值时catch 所有 异常:

Actually I'd say it is. You usually want to catch all exceptions from working with the value:

try {
    const createdUser = await this.User.create(userInfo);

    console.log(createdUser)
    // business logic goes here
} catch (error) {
    console.error(error) // from creation or business logic
}

如果您只想从 promise 中捕获和处理错误,您有以下三种选择:

If you want to catch and handle errors only from the promise, you have three choices:

  • 在外部声明变量,并根据是否有异常进行分支.这可以采取多种形式,例如

  • Declare the variable outside, and branch depending on whether there was an exception or not. That can take various forms, like

  • catch块中的变量赋值
  • return 提前或重新throw catch 块中的异常
  • 设置catch块是否捕获异常的标志,并在if条件下测试
  • 测试已分配的变量值
  • assign a default value to the variable in the catch block
  • return early or re-throw an exception from the catch block
  • set a flag whether the catch block caught an exception, and test for it in an if condition
  • test for the value of the variable to have been assigned
  let createdUser; // or use `var` inside the block
  try {
      createdUser = await this.User.create(userInfo);
  } catch (error) {
      console.error(error) // from creation
  }
  if (createdUser) { // user was successfully created
      console.log(createdUser)
      // business logic goes here
  }

  • 测试捕获的异常的类型,并根据它处理或重新抛出它.

  • Test the caught exception for its type, and handle or rethrow it based on that.

      try {
          const createdUser = await this.User.create(userInfo);
          // user was successfully created
          console.log(createdUser)
          // business logic goes here
      } catch (error) {
          if (error instanceof CreationError) {
              console.error(error) // from creation
          } else {
              throw error;
          }
      }
    

    不幸的是,标准 JavaScript(仍然)没有对 条件异常.

    Unfortunately, standard JavaScript (still) doesn't have syntax support for conditional exceptions.

    如果你的方法没有返回因足够具体的错误而被拒绝的承诺,你可以通过在 .catch() 处理程序中重新抛出更合适的东西来自己做:

    If your method doesn't return promises that are rejected with specific enough errors, you can do that yourself by re-throwing something more appropriate in a .catch() handler:

      try {
          const createdUser = await this.User.create(userInfo).catch(err => {
              throw new CreationError(err.message, {code: "USER_CREATE"});
          });
          …
      } …
    

    另请参阅处理承诺链中的多个捕获,了解 pre-async/等待这个版本.

    See also Handling multiple catches in promise chain for the pre-async/await version of this.

    使用带有两个回调的then而不是try/<代码>捕获.这确实是最不丑陋的方式,我个人的建议也是因为它的简单性和正确性,不依赖标记的错误或结果值的外观来区分履行和拒绝承诺:

    Use then with two callbacks instead of try/catch. This really is the least ugly way and my personal recommendation also for its simplicity and correctness, not relying on tagged errors or looks of the result value to distinguish between fulfillment and rejection of the promise:

      await this.User.create(userInfo).then(createdUser => {
          // user was successfully created
          console.log(createdUser)
          // business logic goes here
      }, error => {
          console.error(error) // from creation
      });
    

    当然它带来了引入回调函数的缺点,这意味着你不能轻易break/continue循环或提前returns来自外部函数.

    Of course it comes with the drawback of introducing callback functions, meaning you cannot as easily break/continue loops or do early returns from the outer function.

    这篇关于正确的 Try...Catch 语法使用 Async/Await的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆