質問編集履歴

1 OK NG

murabito

murabito score 22

2019/02/17 15:22  投稿

PromiseをネストしないでPromiseをチェーンしようとしているがうまくいかない
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
```
  • JavaScript

    21496 questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • Node.js

    2466 questions

    Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る