JS Promise での resolve と .then の使い方
why
(async () => { })()
の無名/即時 関数が npm/prompt で出てきて、web の実行環境で動かしたところ
Terminal で動かした場合と異なり、Promise(pending) になってしまった
そこで「 Promise オブジェクトの resolve...? 一体なんだそれ?」ってなったので 調べてみる。
reject や Promise.all などは後回しにして、今回は reslove と .then での展開についてまとめた。
MDN desc
Global Object の一つ。
何かと何かの間に挟むもの。非同期通信で使われる。
非同期のメソッド(関数のことか?)が 同期の値を返す。
即座に返す代わりに、未来のあるポイントで返すという約束である Promise を返す。
Promise には pending, fulfill, reject, の 3 つがある
.then の fulfill の時 非同期のアクションが起こり
.then の Reject 、または .catch の Reject でエラー処理になる
return でどちらも次の pending な Promise を返す
handler とあるので、イベントのように 条件を fulfil した時にそのハンドラ、エラーが出たときのハンドラーと動くと予想する、しかし return はマジでわからねえ
MDN EXAMPLE
抽象的なコードと説明は訳がわからないから動くサンプルを見てみる
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] が出る
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 で使う必要があるようだ。