TypeScriptなどで利用可能な新しいAsync/Await
機能の平坦性が好きです。しかし、後で使用するためにtry...catch
ブロックの外側でawait
ingである変数を宣言しなければならないという事実が好きではありません。そのようです:
let createdUser
try {
createdUser = await this.User.create(userInfo)
} catch (error) {
console.error(error)
}
console.log(createdUser)
// business
// logic
// goes
// here
間違っている場合は修正してください。ただし、try
本体に複数行のビジネスロジックを配置するのがベストプラクティスのようですnotので、createdUser
を宣言する代わりにブロック、ブロック内での割り当て、およびその後の使用。
この場合のベストプラクティスは何ですか?
Tryボディに複数行のビジネスロジックを配置しないことがベストプラクティスのようです
実際にそうだと思います。通常、値の操作からの例外をcatch
allしたい場合:
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からのエラーのみをキャッチして処理する場合、3つの選択肢があります。
変数を外部で宣言し、例外があったかどうかに応じて分岐します。それは次のようなさまざまな形をとることができます
catch
ブロック内の変数にデフォルト値を割り当てますreturn
Earlyまたはre _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(まだ)では 条件付き例外 の構文サポートはありません。
then
/try
の代わりに catch
2つのコールバックを使用 を使用します。これは最もleastい方法であり、その単純さと正確さについても私の個人的な推奨事項です。タグ付きエラーや結果値の外観に依存せず、約束の履行と拒否を区別します。
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
ループを簡単に実行したり、外部関数から早期にreturn
sを実行したりすることはできません。
もう1つの簡単な方法は、promise関数に.catchを追加することです。例:
const createdUser = await this.User.create(userInfo).catch( error => {
// handle error
})
@Bergi Answerは良いですが、古いthen()メソッドに戻る必要があるため、最善の方法ではないと思うので、非同期関数でエラーをキャッチする方が良いと思います
async function someAsyncFunction(){
const createdUser = await this.User.create(userInfo);
console.log(createdUser)
}
someAsyncFunction().catch(console.log);
await
があり、すべてのエラーをキャッチする必要がある場合はどうでしょうか。to()
関数を宣言できます
function to(promise) {
return promise.then(data => {
return [null, data];
})
.catch(err => [err]);
}
その後
async function someAsyncFunction(){
let err, createdUser, anotherUser;
[err, createdUser] = await to(this.User.create(userInfo));
if (err) console.log(`Error is ${err}`);
else console.log(`createdUser is ${createdUser}`);
[err, anotherUser] = await to(this.User.create(anotherUserInfo));
if (err) console.log(`Error is ${err}`);
else console.log(`anotherUser is ${anotherUser}`);
}
someAsyncFunction();
これを読むときは、「this.User.createを待ちます」。
最後に、モジュール「to.js」を作成するか、単に await-to-js モジュールを使用できます。
to
関数の詳細については、 この投稿 で入手できます