Promiseの基本の基本を段階的に理解する
以下はこのサイトを見ながらとったメモ
こんな非同期関数を考えた時、どういう問題が生じるかを見ていく
これはPromise以前の話
コールバック関数の話
code:ts
const double = (data: number, callback: (n: number) => void) => {
setTimeout(() => {
callback(data * 2);
}, Math.random() * 1000);
};
入れ子で使った時に、2つの問題が生じる
ネストが深くなる
code:ts
const nest = () => {
double(2, n => {
console.log(n1: ${n});
double(3, n => {
console.log(n2: ${n});
double(4, n => {
console.log(n3: ${n});
});
});
});
};
実行するタイミングが不定
code: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で書き直す
code:ts
const doubleP = (data: number) =>
new Promise(callback => {
setTimeout(() => {
callback(data * 2);
}, Math.random() * 1000);
});
Promiseの引数に取る関数のインターフェースについては一旦無視しよう
以下を見ると、上に挙げた2つの問題が解決されていることがわかる
code: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を定義して結果を見てみる
code: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});
});
};