Correct Try…Catch Syntax Using Async/Await

前端 未结 4 1116
闹比i
闹比i 2020-11-22 05:01

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

4条回答
  •  萌比男神i
    2020-11-22 05:40

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

    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
    }
    

    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

      • 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;
          }
      }
      

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

    • 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
      });
      

      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.

提交回复
热议问题