Promise の落とし穴
一般的なミスを避ける
Promise は他の値と同じようには動かない
ほとんどの値と違い、直接その値を出力できません:
// Promise では意味がない:console.log(Promise.resolve(42));
// `.then` インターフェースを使う必要があります:Promise.resolve(42).then(value => console.log(value));Promise はミスを警告しない
典型的なミスです。
さまざまな理由で、TC39 は .then と .catch に null を渡すことを許容しました。たとえば、.then(null, null) は有効で、チェーン内のその「ステップ」をスキップするという動作が求められます。
この決定の不本意な結果は、ちょっとした手違いで簡単に壊れてしまうことです。
例で確認
次のミニチャレンジを見てみましょう: 以下のどのオプションが console.log に 42 を出力するでしょうか?
// オプション #1:Promise.resolve(42).then(console.log());
// オプション #2:Promise.resolve(42).then(console.log);
// オプション #3:Promise.resolve(42).then(value => console.log(value));
// オプション #4:Promise.resolve(42) .then(console.log()) .then(console.log);答え
正解は #2、#3、#4 です。
なぜでしょうか? .then() に渡された 型 を見てみましょう。
var arg1 = console.log();var arg2 = console.log;var arg3 = value => console.log(value);
typeof arg1 === "undefined";typeof arg2 === "function";typeof arg3 === "function";4番目のオプションがどう動くのかまだ気になりますか?
実際には次のように実行されます。
// Option #4 - effectivelyPromise.resolve(42) .then(undefined) // 値に影響はなく、次の `.then(fn)` にそのまま渡される .then(console.log);