LoginSignup
47
21

More than 3 years have passed since last update.

Promiseのresolveとrejectの両方を呼び出したらどうなってしまうのか?

Last updated at Posted at 2019-11-12

Promiseは次のサンプルコードように、失敗したらrejectを、成功したらresolveを呼び出すような書き方をする。

new Promise((resolve, reject) => {
  // ...
  if (err) {
    reject(err)
  } else {
    resolve()
  }
})

このサンプルコードは、正常系と異常系でif分岐されており、resolverejectが両方呼ばれる可能性はない。

もしも、resolverejectの両方を呼び出したらどうなるのだろうか?

new Promise((resolve, reject) => {
  reject()
  resolve()
})

普通はこんなことはしないだろうが、Promiseの仕様を知っておくのは良さそうだ。

実験1: resolverejectの順で呼んでみる

実験してみよう。まずは、resolverejectの順で呼び出してみよう。

new Promise((resolve, reject) => {
    resolve()
    reject()
}).then(value => console.log('success'))
  .catch(reason => console.log('failure'))
//=> success

この実行結果は、「success」になり、resolveが尊重されたかたちになった。

実験2: rejectresolveの順で呼んでみる

今度は逆に、rejectのほうを先に呼び出してみることにする。

new Promise((resolve, reject) => {
    reject()
    resolve()
}).then(value => console.log('success'))
  .catch(reason => console.log('failure'))
//=> failure

今度の結果は「failure」になった。rejectのほうが採用されたことが分かる。

結論: 先に呼ばれたほうが採用される

「Promiseのresolverejectの両方を呼び出したらどうなってしまうのか?」の疑問への答えとしては、「先に呼ばれたほうが採用される」ということになりそうだ。

余談: 先勝ちと言っても、処理が中断されるわけではない

ちなみに、resolverejectどちらかが採用されるとは言え、Promiseに渡したexecuterの処理が中断されるわけではない。例えば、下記のコードでは、①でresolveが採用されるが、そのあとの②③の行も実行される。

new Promise((resolve, reject) => {
    resolve() // ①
    console.log('after resolve') // ②
    reject() // ③
}).then(value => console.log('success'))

Learn more

47
21
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
47
21