generated at
Promiseの基本の基本を段階的に理解する
とほほのPromise入門がとにかくわかりやすい
以下はこのサイトを見ながらとったメモ


こんな非同期関数を考えた時、どういう問題が生じるかを見ていく
これはPromise以前の話
コールバック関数の話
ts
const double = (data: number, callback: (n: number) => void) => { setTimeout(() => { callback(data * 2); }, Math.random() * 1000); };

入れ子で使った時に、2つの問題が生じる
ネストが深くなる
ts
const nest = () => { double(2, n => { console.log(`n1: ${n}`); double(3, n => { console.log(`n2: ${n}`); double(4, n => { console.log(`n3: ${n}`); }); }); }); };
実行するタイミングが不定
ts
const order = () => { double(2, n => { console.log(`n1: ${n}`); }); double(3, n => { console.log(`n2: ${n}`); }); double(4, n => { console.log(`n3: ${n}`); }); };
この結果は n1 , n2 , n3 がどの順に実行されるかは毎回異なる


上に書いた関数をPromiseで書き直す
ts
const doubleP = (data: number) => new Promise(callback => { setTimeout(() => { callback(data * 2); }, Math.random() * 1000); });
Promiseの引数に取る関数のインターフェースについては一旦無視しよう


以下を見ると、上に挙げた2つの問題が解決されていることがわかる
ts
const nestP = () => { doubleP(2) .then(n => { console.log(`n1: ${n}`); return doubleP(3); }) .then(n => { console.log(`n2: ${n}`); return doubleP(4); }) .then(n => { console.log(`n3: ${n}`); }); };
then 節はチェーンすることができ、一つ前の戻り値を引数として受け取る
TSの型推論を見るとよく分かる
返すものはこのコード例のように毎回新しいPromiseを返すものでも良いし、普通に値を返してもいい
基本的には前者の使い方をするのかな #??

エラー処理
30%の確率で失敗するPromiseを返す関数 doubleE を定義して結果を見てみる
ts
const doubleE = (data: number) => new Promise((f, e) => { setTimeout(() => { if (Math.random() < 0.3) { e(new Error("ERROR!")); } else { f(data * 2); } }, Math.random() * 1000); }); const nestE = () => { doubleE(2) .then(n => { console.log(`success: ${n}`); }) .catch(e => { console.log(`error: ${e}`); }); };