簡単で、catch
以降に処理を書くとエラー発生の有無に関わらず実行される。jsbin
Promise.resolve()
.then(() => console.log('通常時: 1'))
.catch(err => {})
.then(() => console.log('通常時: 2'))
// -> 通常時: 1
// 通常時: 2
Promise.reject(new Error())
.then(() => console.log('エラー時: 実行されない'))
.catch(err => {})
.then(() => console.log('エラー時: 1'))
// -> エラー時: 1
どのようなケースで使うか
あるスコープで発生したゴミをそのスコープ内で掃除したいというケースなどに有用。jsbin
const example = () => {
const p = Promise.resolve()
.then(() => console.log('ゴミが発生'))
.then(() => {
console.log('エラーが発生')
return Promise.reject(new Error)
})
.then(() => console.log('通常なら実行される')) // スキップされる
.catch(err => {})
.then(() => console.log('ゴミを処理')) // エラーの有無にかかわらず実行される
return p
}
example()
捕捉したエラーを変数に確保し、共通処理後にリジェクトするパターン
example()
の呼び出し元でエラーハンドリングを行いたいことがある。
スコープ内でcatch
したエラーを共通処理後にもう一度reject
してあげると、以降のthen
はスキップされ次に現れるcatch
でエラーを捕捉できる。jsbin
const example = () => {
let error
const p = Promise.resolve()
.then(() => console.log('ゴミが発生'))
.then(() => {
console.log('エラーが発生')
return Promise.reject(new Error)
})
.then(() => console.log('通常なら実行される')) // スキップされる
.catch(err => error = err) // キャッチしたエラーを変数に格納
.then(() => {
console.log('ゴミを処理') // エラーの有無にかかわらず実行される
if (error) {
return Promise.reject(error) // エラーがある場合はrejectする
}
})
return p // Promiseインスタンスを返却
}
example()
.then(() => console.log('exampleが通常なら実行される')) // スキップされる
.catch((err) => console.log('exampleがエラーなら実行される')) // 実行される
捕捉したエラーを共有処理に渡し、共通処理後にリジェクトするパターン
次のように、catch
で捕捉したエラーをreturn
し、次のthen
に渡すというエラーを変数に確保しないパターンもある。jsbin
const example = () => {
return Promise.reject(new Error())
.catch(err => err)
.then((err) => {
if (err) {
return Promise.reject(err)
}
})
}
example()
.catch((err) => console.log(err)) // 実行される
一時確保用の余計な変数がなくなって良さそうに見えるけど、catch
前のチェーンで何かを渡している場合は、エラーが起こらないとcatch
後のthen
にその値が渡ってしまい、エラーではないのにreject
してしまう。jsbin
const example = () => {
return Promise.resolve('エラーではない何か')
.catch(err => err)
.then((err) => {
console.log(err) // -> 'エラーではない何か'
if (err) {
return Promise.reject(err)
}
})
}
example()
.catch((err) => console.log(err)) // -> 'エラーではない何か'
これは意図しない挙動で、catch
後のthen
に渡ってくる引数がエラーなのかを判定しなければならない。jsbin
const example = () => {
return Promise.resolve('エラーではない何か')
.catch(err => err)
.then((arg) => {
console.log(arg) // -> 'エラーではない何か'
if (arg instanceof Error) {
return Promise.reject(arg)
}
})
}
example()
.catch((err) => console.log(err)) // 実行されない