KAEDE Hack blog

JavaScript 中心に ライブラリなどの使い方を解説する技術ブログ。

JS Promise での resolve と .then の使い方

why

(async () => {
})()

の無名/即時 関数が npm/prompt で出てきて、web の実行環境で動かしたところ

Terminal で動かした場合と異なり、Promise(pending) になってしまった

そこで「 Promise オブジェクトの resolve...? 一体なんだそれ?」ってなったので 調べてみる。

reject や Promise.all などは後回しにして、今回は reslove と .then での展開についてまとめた。

MDN desc

Global Object の一つ。

developer.mozilla.org

何かと何かの間に挟むもの。非同期通信で使われる。

非同期のメソッド(関数のことか?)が 同期の値を返す。

即座に返す代わりに、未来のあるポイントで返すという約束である Promise を返す。

Promise には pending, fulfill, reject, の 3 つがある

.then の fulfill の時 非同期のアクションが起こり

.then の Reject 、または .catch の Reject でエラー処理になる

return でどちらも次の pending な Promise を返す

handler とあるので、イベントのように 条件を fulfil した時にそのハンドラ、エラーが出たときのハンドラーと動くと予想する、しかし return はマジでわからねえ

MDN EXAMPLE

抽象的なコードと説明は訳がわからないから動くサンプルを見てみる

developer.mozilla.org

let myFirstPromise = new Promise((resolve, reject) => {
  setTimeout( function() {
    resolve('Success')
  }, 250)
})

Promise object を作成する。

resolve と reject は自動的に内部に作られると予想する

中では setTimeout で即時関数を使って 250ms 後に 内部の resolve に 'Success' という文字列を渡す

myFirstPromise.then((successMessage) => {
  console.log(`Yay!: ${successMessage}`);
})

今作成した Promise に .then を使うことで resolve になる。なので resolve に渡されている 'Success' を受け取って表示できる

全然わからないが、resolve に渡したものを .then の一つ目のスコープで使えると解釈する

実行時間は .then だとその後の処理より遅くなる。

Promise で resolve に渡して .then で使用する場合、非同期として処理のスレッドが分岐するので、その後にシンプルに書いてあるコードは先に実行される。

const promiseA = new Promise( (resolutionFunc, rejection) => {
  resolutionFunc(777)
});
promiseA.then((val)=> console.log('async logging has val: ', val));
console.log('immediate logging');

これで新しく作った Promise Object の引数に 解決の時の関数、拒否の時の値をとり、 解決の時の関数に 777 という値をいれる

それに then で 引数の関数に val をとり、console.log で val を表示する

.then を足されると、Promise を解決することになるのだと予想する

しかしその次に書いてある console.log は非同期を使わないので早く、 解決処理を行ってる間に先に表示される。なので結果は

immediate logging
async logging has val:  777

となる


new Promise( A, B) の引数の名前は自由

前回の

let myFirstPromise = new Promise((resolve, reject) => {
  setTimeout( function() {
    resolve('Success')
  }, 250)
})

との違いとしては、 Promise を new で作るときの引数が違う。

resolve, reject で決まっているわけではなく、好きな名前の関数を二つ指定することができて、前者に指定されたものは resolve として扱われるので、.then の中で使えるようだ

よって

const promiseHoge = new Promise( (hogehoge, rejection) => {
  hogehoge(777)
});
promiseHoge.then((hogehoge)=> console.log('hogehoge val: ', hogehoge));
console.log('immediate logging');

このように hogehoge とか全然違う名前でも、resolve として扱うことができた。


.then を使わない場合は [object Promise] が出る

developer.mozilla.org

const promiseA = new Promise( (resolutionFunc, rejection) => {
  resolutionFunc(777)
});
promiseA.then((val)=> console.log('async logging has val: ', val));
console.log('immediate logging');
console.log(`promiseA: ${promiseA}`)

.then を使わずに、そのまま promise を使おうとしてみると

immediate logging
promiseA: [object Promise]
async logging has val:  777

[object Promise] として中身が出ないので .then で使う必要があるようだ。