1つの非同期処理が成功した時に、後続の非同期処理を行いたいのですが、Promiseをネストせずに書こうとすると上手くいきません。
前提として、最初の非同期処理と後続の非同期処理では成功した時も、エラーが発生した時もそれぞれ異なる処理を行います。
また、async awaitを使わないというのも前提となります。
Promiseでネストさせるのは宜しくないようなので、ネストを回避した書き方を身に付けたいのですが、例外が発生する場合に上手くかけません。
正しい書き方をご教示頂けますと幸いです。
両方の非同期処理がresolveされるケース
ネストした書き方
const async1 = () => { return new Promise((resolve, reject) => { setTimeout(() => { return resolve('async1 success') }, 1000) }) } const async2 = () => { return new Promise((resolve, reject) => { setTimeout(() => { return resolve('async2 success') }, 1000) }) } async1() .then(result => { console.log('then1:', result) return async2() .then(result => console.log('then2:', result)) .catch(error => console.error('catch2:', error)) }) .catch(error => console.error('catch1:', error))
ネストさせない書き方
const async1 = () => { return new Promise((resolve, reject) => { setTimeout(() => { return resolve('async1 success') }, 1000) }) } const async2 = () => { return new Promise((resolve, reject) => { setTimeout(() => { return resolve('async2 success') }, 1000) }) } async1() .then(result => { console.log('then1:', result) return async2() }) .catch(error => console.error('catch1:', error)) .then(result => console.log('then2:', result)) .catch(error => console.error('catch2:', error))
期待するアウトプット
then1: async1 success then2: async2 success
実際のアウトプット(OK!)
この場合は、ネストする書き方もネストしない書き方も期待したアウトプットになっている。
then1: async1 success then2: async2 success
最初の非同期処理がresolveされ、後続の非同期処理がrejectの場合
ネストされた書き方
const async1 = () => { return new Promise((resolve, reject) => { setTimeout(() => { return resolve('async1 success') }, 1000) }) } const async2 = () => { return new Promise((resolve, reject) => { setTimeout(() => { return reject('async2 error') }, 1000) }) } async1() .then(result => { console.log('then1:', result) return async2() .then(result => console.log('then2:', result)) .catch(error => console.error('catch2:', error)) }) .catch(error => console.error('catch1:', error))
ネストさせない書き方
const async1 = () => { return new Promise((resolve, reject) => { setTimeout(() => { return resolve('async1 success') }, 1000) }) } const async2 = () => { return new Promise((resolve, reject) => { setTimeout(() => { return reject('async2 error') }, 1000) }) } async1() .then(result => { console.log('then1:', result) return async2() }) .catch(error => console.error('catch1:', error)) .then(result => console.log('then2:', result)) .catch(error => console.error('catch2:', error))
期待するアウトプット
then1: async1 success catch2: async2 error
※ 最初の非同期処理と異なるエラーハンドリングが後続の非同期処理でできれば、実際は2つ目のcatchブロックでハンドリングすることは必須ではない。
実際のアウトプット(NG!)
この場合は、ネストされた書き方は期待通りにアウトプットを得られるが、ネストさせない書き方は間違っているのか以下のアウトプットになってしまう。
then1: async1 success catch1: async2 error then2: undefined
最初の非同期処理でrejectになった場合
ネストする書き方
const async1 = () => { return new Promise((resolve, reject) => { setTimeout(() => { return reject('async1 error') }, 1000) }) } const async2 = () => { return new Promise((resolve, reject) => { setTimeout(() => {}, 1000) }) } async1() .then(result => { console.log('then1:', result) return async2() .then(result => console.log('then2:', result)) .catch(error => console.error('catch2:', error)) }) .catch(error => console.error('catch1:', error))
ネストさせない書き方
const async1 = () => { return new Promise((resolve, reject) => { setTimeout(() => { return reject('async1 error') }, 1000) }) } const async2 = () => { return new Promise((resolve, reject) => { setTimeout(() => {}, 1000) }) } async1() .then(result => { console.log('then1:', result) return async2() }) .catch(error => console.error('catch1:', error)) .then(result => console.log('then2:', result)) .catch(error => console.error('catch2:', error))
期待するアウトプット
catch1: async1 error
実際のアウトプット(NG!)
catch1: async1 error then2: undefined
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/02/18 12:56
2019/02/19 12:46