新年の始まりです。多くの人がもっとアクティブになることを約束していますが、私は をもっと怠惰にする方法を紹介します… 、つまり。 Promise JavaScript Promise すぐに理解できるようになります。 https://www.youtube.com/watch?v=qj7diPVWTqY?embedable=true まず、基本的な の例を見てみましょう。ここに、ミリ秒単位の時間と値を取る sleep という関数があります。待機する必要があるミリ秒数の間 を実行する promise を返します。 Promise はその値で解決されます。 Promise setTimeout /** * @template ValueType * @param {number} ms * @param {ValueType} value * @returns {Promise<ValueType>} */ function sleep(ms, value) { return new Promise((resolve) => { setTimeout(() => resolve(value), ms); }); } それはこのように動作します: 引数 と を指定して 関数を待機すると、1 秒後に に文字列 'Yawn & Stretch' が記録されます。 1000 'Yawn & stretch' sleep console それについて特別なことは何もありません。おそらく期待どおりに動作しますが、返された をすぐに するのではなく、変数として保存して後で すると、少し奇妙になります。 Promise await await const nap = sleep(1000, 'Yawn & stretch') ここで、時間がかかる他の作業 (次の例を入力するなど) を行い、 変数を するとします。 await nap 解決するまでに 1 秒の遅延が予想されるかもしれませんが、実際にはすぐに解決されます。 を作成するときはいつでも、それが担当する非同期機能をインスタンス化します。 Promise この例では、 変数を定義した瞬間に、 を実行する が作成されます。私はタイピングが遅いので、待機するまでに は されます。 nap setTimeout Promise Promise await つまり、 は熱心です。彼らはあなたが彼らを のを待ちません。 Promise await 場合によっては、これは良いことです。それ以外の場合は、不要なリソースの使用につながる可能性があります。これらのシナリオでは、 のように見えるものが必要になる場合がありますが、 必要なときにのみインスタンス化します。 Promise 遅延評価 先に進む前に、興味深いことをお見せしたいと思います。 JavaScript で できるのは だけではありません。 メソッドでプレーンな を作成すると、 と同じように実際にそのオブジェクトを できます。 await Promise .then() Object await Promise これはちょっと奇妙ですが、 のように てもそうではないさまざまなオブジェクトを作成することもできます。これらのオブジェクトは「 」。 Promise 見え セナブルズ それを念頭に置いて、新しいものを作成しましょう 組み込みの コンストラクターを拡張する と呼ばれます。 Promise の拡張は厳密には必要ではありませんが、 などを使用して に似せたものにします。 クラス Promise LazyPromise instanceof Promise class LazyPromise extends Promise { /** @param {ConstructorParameters<PromiseConstructor>[0]} executor */ constructor(executor) { super(executor); if (typeof executor !== 'function') { throw new TypeError(`LazyPromise executor is not a function`); } this._executor = executor; } then() { this.promise = this.promise || new Promise(this._executor); return this.promise.then.apply(this.promise, arguments); } } 注目すべき部分は メソッドです。標準の のデフォルトの動作をハイジャックして、実際の を作成する前に メソッドが実行されるまで待機します。 then() Promise Promise .then() これにより、実際に呼び出すまで非同期機能のインスタンス化が回避されます。そして、明示的に を呼び出しても、 を使用しても機能します。 .then() await それでは、元の 関数の を に置き換えるとどうなるか見てみましょう。もう一度、結果を 変数に代入します。 sleep Promise LazyPromise nap function sleep(ms, value) { return new LazyPromise((resolve) => { setTimeout(() => resolve(value), ms); }); } const nap = sleep(1000, 'Yawn & stretch') 次に、時間をかけて 行を入力して実行します。 await nap 今回は、変数が作成されてからの経過時間に関係なく、 が解決されるまでに 1 秒の遅延が見られます。 Promise (この実装は新しい を 1 回だけ作成し、その後の呼び出しでそれを参照することに注意してください。したがって、再度 すると、通常の と同様にすぐに解決されます) Promise await Promise もちろん、これは製品コードではおそらく見られない些細な例ですが、遅延評価された のようなオブジェクトを使用するプロジェクトはたくさんあります。おそらく最も一般的な例は、データベース と次のようなクエリビルダーです。 また . Promise ORM Knex.js プリズマ 以下の疑似コードを検討してください。これは、次のクエリ ビルダーのいくつかに触発されています。 const query = db('user') .select('name') .limit(10) const users = await query テーブルに移動し、最初の 10 個のエントリを選択してそれらの名前を返すデータベース クエリを作成します。理論的には、これは通常の でうまく機能します。 "user" Promise しかし、クエリ文字列パラメーターなどの特定の条件に基づいてクエリを変更したい場合はどうすればよいでしょうか?最終的に を待つ前に、クエリの変更を続行できると便利です。 Promise const query = db('user') .select('name') .limit(10) if (orderBy) { query.orderBy(orderBy) } if (limit) { query.limit(limit) } if (id) { query.where({ id: id }) } const users = await query 元のデータベース クエリが標準の である場合、変数を割り当てるとすぐにクエリが積極的にインスタンス化され、後で変更することはできません。 Promise 遅延評価を使用すると、このようなコードを記述して、より簡単に追跡でき、開発者のエクスペリエンスが向上し、必要なときに 1 回だけクエリを実行できます。 これは、遅延評価が優れている 1 つの例です。また、HTTP 要求の構築、変更、調整などにも役立つ場合があります。 Lazy は適切なユースケースには非常に優れていますが、すべての を置き換える必要があるとは言えません。場合によっては、積極的にインスタンス化して、できるだけ早く応答を準備することが有益です。 Promise Promise これは、「場合による」シナリオの 1 つです。しかし、次に誰かがあなたに をするように頼んだら、それについて怠けていると考えてください ( ͡° ͜ʖ ͡°)。 Promise 読んでいただきありがとうございます。この記事が気に入ったらどうぞ .それは私をサポートする最良の方法の 1 つです。あなたもすることができます また 新しい記事が公開されたときに知りたい場合。 共有する ニュースレターにサインアップする Twitterで私に従ってください 最初に公開された austingil.com .