みなさんこんにちは。私は次男です。 最初の2つの記事が公開された後、何人かのネットユーザーが裏で私にいくつかの質問をしたので、それらをまとめて要約しました。この記事はネットユーザーの質問への回答であると同時に、前の2つの記事の補足とレビューでもあります。 最初の 2 つの記事へのリンクは次のとおりです。 Node.js のコアイベントループのグラフィカルな説明 マルチグラフ分析式 async=Promise+Generator+Automatic Executor 図1: 非同期関数のコード例 質問 0 : 前の記事で説明したジェネレーターと自動実行プログラムは、異なるスレッドで実行されますか? 回答 0 : ジェネレーターとエグゼキューターは両方とも、JS コードを実行するメイン スレッドであるイベント ループ スレッドで実行されます。もう一度強調しておきますが、これらは 2 つのスレッドで実行されているわけではありません。 Node.js公式サイトのevent-loopの説明をもう一度見てみましょう。重要な点を強調します。JS コードはシングルスレッド方式で実行されます。 イベントループにより、 JavaScript はシングル スレッドであるにもかかわらず、 可能な限り操作をシステムカーネルにオフロードすることで、 Node.js は非ブロッキングI / O 操作を実行できるようになります。 質問 1 : ステートメント await p は非同期要求を生成しますか? 回答 1 : いいえ、そうではありません。 await は、p の状態が保留から解決に変化するか、保留から拒否に変化するかを待機するだけです。 質問 2 : 非同期リクエストはいつ生成されますか? 回答 2 : setTimeout が実行されると Promise executor で生成されます。 次のテキストでは、new Promise() を呼び出すときに渡されるコールバック (resolve, reject)=>{ /* your code */ は、executor と呼ばれます。パラメータresolveとrejectはPromise自体によって実装されます。このエグゼキュータは、new Promise() が呼び出されるとすぐに実行されることに注意してください。 executor で fs.read(fd[, options], callback) のようなステートメントを実行すると、同様に、fs.read() が呼び出されたときに非同期リクエストが生成されます。 質問3 :pの状態が変化した後、resolve(200)を通過した200が変数resの評価結果になるのはなぜですか? 回答 3 : これが、await の背後にある実装原則を理解する必要がある理由です。図 2 と 4 を参考にしてこれを確認してみましょう。 図 2 に示すように、まず async 関数がジェネレーター関数に変換されます。ただし、ジェネレーター関数はそれ自体では自動的に実行できないため、自動実行プログラムと組み合わせて実行する必要があります。オートマトンとは愛情深い母親のようなもので、ジェネレーターとは純真な幼児のようなものだ。子どもは一定の距離を歩くたびに立ち止まり、後ろからついてくる母親を振り返り、母親から励ましやご褒美をもらって次の目標へと進んでいきます。 図2: 非同期関数をジェネレータ関数に変換する例 図 4 を説明する前に、yield 式と yield ステートメントという 2 つの重要な概念を確認する必要があります。図3に示すように:
図 3 には、ジェネレーター関数の実行の一時停止ポイント、つまり yield 式が評価された後、yield ステートメントが返される前という重要なポイントも示されています。 図3: 収量式と収量ステートメントの比較 質問 3 にもっとわかりやすく答えるために、次兄が図 4 を描いてくれました。 ① このステップでは、エグゼキュータを介してジェネレータの呼び出しを開始します。 ② ここで実際のジェネレータの呼び出しが発生しますが、ジェネレータ関数はステップ ② では何も行わず、すぐにイテレータを返します。 ③ここから自動アクチュエータは駆動ジェネレータモードに入ります。 ③ このステップでは、g.next() が初めて実行されるときに値を挿入できないため、パラメータデータに値を割り当てません。 ④ このステップで g.next() が呼び出されるたびに、ジェネレーターは yield で最後に一時停止した位置から実行を開始し、再び yield に遭遇するまで実行されます。 ⑤ したがって、g.next() の最初の呼び出しにより、左のジェネレーター関数は関数の先頭から yield に遭遇するまで実行されます。 ⑤でマークされたコード実行プロセスでは、実際に Promise オブジェクトが作成され、Promise executor に 1 秒のタイマーが設定されていることがわかります。このエグゼキュータは Promise オブジェクトが作成されると同時に実行されますが、⑦のコードは 1 秒後まで実行されないことに注意してください。 ⑥ジェネレータ関数が一時停止する前に、yield式の評価結果が{value:xxx, done:xxx}を通じてg.next()の呼び出し元に返されます。これは右図の④の位置です。 したがって、右の図の位置 ④ にある変数 result は { value: p, done: false} であると推測できるはずです。ここでpは⑤の実行中に生成されたPromiseオブジェクトです。 このようにして、Promise オブジェクトはジェネレーター関数と自動エグゼキューターの間を流れます。それはとても独創的なプロセスです。 そうすれば、右側のステートメント result.value.then(callback) を見ても混乱することはありません。これは Promise の標準的な使用法です。 p の状態が解決されると、当然 ⑧ のコールバックが実行される機会が得られます。 ⑦ 1秒があっという間に経過し、resolve(200)が実行できるようになります。これを実行するとpの状態が解決されるため、⑧で辛抱強く待機していたコールバックが動作を開始します。 ⑧ はい、この時点でデータの値は200です。 Promise の使用に慣れている場合、これは非常に自然なことです。 ⑨ 自動実行プログラムは next(data) を再度実行します。しかし今回は実際のパラメータ200が渡されます。そのため、今回は④で実行されるコードは g.next(200) になります。 ⑩自動実行プログラムはg.next(200)を実行し、必然的にジェネレータ関数を開始して前進を続けます。 前回ジェネレータ関数がどこで停止したかを覚えていますか?はい、左側の⑤の矢印の位置です。ジェネレータ関数が再開したときに最初に行うことは、yield ステートメントを評価することです。 g.next() のように駆動すると、yield ステートメントは undefined を返します。しかし今回は g.next(200) を実行する点が異なります。非常に巧妙なことに、 next() に渡された引数 200 は、 yield ステートメントの戻り値として左変数 res に割り当てられます。 図4: ジェネレーター + オートメーターの詳細 図 1 のサンプル コードをもう一度見て、要約してみましょう。
図5: 図1と同じ |
<<: VMware は、ワークロードのパフォーマンスを向上させ、企業の TCO を削減する新しいコンピューティングおよびストレージ ソリューションをリリースしました。
>>: Prometheus、Istio、Hpa、Keda、Karpenter をベースにした K8s アプリケーションとノードの弾力性の実装
以前面接に行ったとき、面接官から JVM のパフォーマンス チューニングについて質問されました。以前...
市場経済の発展に伴い、多くの分野が過当競争の時代に入り、企業が顧客を獲得するためのコストはますます高...
まだご存じないかもしれませんが、EntryBytes は NexusBytes によって作成されたサ...
昨日、その友人は、私のウェブサイトにいくつかのコラムを追加して、私のWebサイトを見せてくれたことを...
多くの電子商取引ウェブサイトは最適化されていますが、実際には、特に中小規模のウェブサイトでは、ウェブ...
思考の観点から共有する、Quanlai - 伝統的な業界におけるインターネットブランドマーケティング...
7月の百度Kステーション事件では、医療系ウェブサイトが大きな損失を被り、百度の大規模調整における最大...
本日、米国サンフランシスコでOracle OpenWorldが開催されました。業界における重要なビジ...
ソフトな物品が効果的であることはわかっていますが、この効果の概念は非常に曖昧です。 SEO の効果を...
現在、Baidu はアルゴリズムを絶えず変更し、さまざまなポリシーを導入しているため、SEO 担当者...
最近、Kubernetes はバージョン 1.20 以降で Docker のサポートを中止することを...
1. 勤勉な編集者のグループ(これについては詳しく説明する必要はありません)。 1.1. フォーラム...
人間社会に大きな構造変化が起こるたびに、土地や資源の合併、富や権力の再編の話が繰り返されるのと同様に...
無料の VPS をお探しですか?永続的な VPS ですか?海外で永久に無料の VPS をお探しですか...
2006 年に設立されたオランダの Access2.IT Group BV (チェック可能: VAT...