1. ホーム
  2. javascript

[解決済み] 非同期/待機を使用した正しい Try...Catch 構文

2023-01-08 11:38:51

質問

新型の平面が好きです。 Async/Await の機能は、Typescript などで利用できます。しかし、私は、私が宣言しなければならない変数が await の外側で try...catch ブロックの外側で、それを後で使うことができます。というように。

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

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

間違っていたら訂正してほしいのですが、ベストプラクティスと思われる ではなく に複数行のビジネス ロジックを配置することは、ベスト プラクティスではないようです。 try ボディに複数行のビジネスロジックを配置することはできないので、代わりに createdUser をブロックの外で宣言し、ブロックの中でそれを代入し、そして後でそれを使用する、という選択肢しか残っていません。

この例でのベストプラクティスは何でしょうか?

どのように解決するのですか?

<ブロッククオート

tryボディの中にビジネスロジックを複数行配置しないのがベストプラクティスと思われます。

実際、そうだと思います。通常は catch すべて の例外が発生し、その値を扱うことができなくなります。

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
}

プロミスからのエラーだけをキャッチして処理したい場合、3つの選択肢があります。

  • 外部で変数を宣言し、例外が発生したかどうかで分岐させる。というように、様々な形をとることができます。

    • で変数にデフォルト値を割り当てる。 catch ブロック
    • return 初期または再 throw からの例外 catch ブロック
    • を使用するかどうかのフラグを設定します。 catch ブロックが例外を捕えたかどうかのフラグを設定し、そのフラグを if 条件
    • 変数の値が代入されているかどうかをテストする
      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
      }
    
    
  • キャッチした例外の型をテストし、それに基づいて処理するか再スローします。

      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 は (まだ) 条件付き例外 .

    もしあなたのメソッドが十分具体的なエラーで拒否されるようなプロミスを返さないのであれば、より適切なものを再度 .catch() ハンドラでより適切なものを投げ直すことによって、自分でそれを行うことができます。

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

    参照 プロミスチェインで複数のキャッチを処理する については、事前に async / await のバージョンになります。

  • 使用方法 then の2つのコールバックで の代わりに try / catch . これは本当に最も醜い方法であり、そのシンプルさと正しさのために私の個人的な推奨でもあります。

      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 ループやDOアーリー return を外側の関数から実行します。