JavaScriptにおけるプロミスチェーンの例外処理
何らかの理由で私たちのプロミスが エラーで終了するとします:
let promise = new Promise(function(resolve, reject) {
setTimeout(function() {
reject('error');
}, 3000);
});
この場合、コードの実行は即座に、
エラーハンドラー関数を持つ then、
または最初に現れる catchのいずれかに
移ります(どちらが先かによります)。
最初の状況の例は以下の通りです:
promise.then(
function(result) {
return result + '1';
}
).then(
function(result) {
return result + '2';
},
function(error) {
// 実行はここに直ちにジャンプする
}
).then(
function(result) {
console.log(result);
}
);
二つ目の状況の例は以下の通りです:
promise.then(
function(result) {
return result + '1';
}
).then(
function(result) {
return result + '2';
}
).catch(
function(error) {
// 実行はここに直ちにジャンプする
}
).then(
function(result) {
console.log(result);
}
);
ハンドラー関数には2つの行動の選択肢があります:
例外的な状況に対処できた場合は、
return を通じて結果を返し、
実行はチェーンに沿って続行されます。
エラーに対処できなかった場合は、
何も返さないか、または throw
を通じて例外をスローすることができます。
この場合、実行は次のエラーキャッチャー
(次に現れる then または catch)
に移ります。
原則として、チェーン内のすべてのエラーは
一箇所で捕捉されます: チェーンの終端に
catch を配置します:
promise.then(
function(result) {
return result + '1';
}
).then(
function(result) {
return result + '2';
}
).catch(
function(error) {
// エラー発生時にここに入る
}
);
例外はプロミス自体で発生する可能性があるほか、
チェーンのどのリンクでも throw
によってスローされる可能性があります:
promise.then(
function(result) {
return result + '1';
}
).then(
function(result) {
if (allGood) {
return result + '2';
} else {
throw new Error('エラー'); // 最も近いキャッチャーにジャンプ
}
}
)
.then(
function(result) {
return result + '3';
}
).catch(
function(error) {
// 最も近いキャッチャー
}
);
catch は、まさにエラーの診断のために
必要であることに留意してください: エラーが
解決可能か否か。エラーが解決可能である場合、
catch はその解決策を自身に続く
then に渡すべきです。
解決不可能な場合(またはこの catch が
その解決方法を知らない場合)、私たちは
何も返さないか、または例外をスローすべきです:
promise.then(
function(result) {
return result + '1';
}
).then(
function(result) {
return result + '2';
}
).catch(
function(error) {
if (errorSolvable) {
return 'data'; // 次の then へ送る
} else {
// 何も返さないか、例外をスローする
}
}
).then(
function(result) {
// ここでエラーを解決する
}
);