ホームページ  >  記事  >  ウェブフロントエンド  >  Angular のzone.js とその仕組みの詳細な分析

Angular のzone.js とその仕組みの詳細な分析

青灯夜游
青灯夜游転載
2022-02-07 10:09:302391ブラウズ

この記事では、Angular のzone.jsを理解し、例を使用してzone.jsの機能を実証し、その背後にある動作原理を簡単に分析します。みんな!

Angular のzone.js とその仕組みの詳細な分析

Angular が zone.js を使用していることを聞いたことがあるかもしれませんが、なぜ Angular は zone.js を使用するのでしょうか?機能が提供されていますか?今日は、zone.js について説明する別の記事を書きます。Angular フレームワークにおけるその役割については、次の記事で説明します。 [関連チュートリアルの推奨事項: "angularTutorial"]

ゾーンとは何ですか? 公式ドキュメントでは次のように説明されています: ゾーンは複数の非同期タスクにまたがる実行コンテキストです。一言で言えば、Zone は非同期タスクを傍受または追跡する特に強力な機能を備えています。以下では、例を使用してその機能を実証し、その背後にある動作原理を簡単に分析します。

<button id="b1">Bind Error</button>
<button id="b2">Cause Error</button>
<script>
  function main() {
    b1.addEventListener(&#39;click&#39;, bindSecondButton);
  }
  function bindSecondButton() {
    b2.addEventListener(&#39;click&#39;, throwError);
  }
  function throwError() {
    throw new Error(&#39;aw shucks&#39;);
  }
  main();
</script>

これは単純な HTML ページです。ページが読み込まれると、最初のボタンにクリック イベントが追加されます。そのクリック イベント関数の機能は、2 番目のボタンにクリック イベントを追加することであり、2 番目のボタンのクリック イベント関数の機能は、例外。最初のボタンと 2 番目のボタンを順番にクリックすると、コンソールに次のように表示されます。コンソール出力? 、まずスタートアップ コードを調整します:

(索引):26 Uncaught Error: aw shucks
    at HTMLButtonElement.throwError ((索引):26:13)

この時点で、コンソール出力は次のとおりです: <pre class="brush:js;toolbar:false;"> Zone.current.fork( { name: &amp;#39;error&amp;#39;, onHandleError: function (parentZoneDelegate, currentZone, targetZone, error) { console.log(error.stack); } } ).fork(Zone.longStackTraceZoneSpec).run(main);</pre> 比較すると、

zone.js のときがわかります。

は導入されていないため、エラーによって呼び出します。スタックは、ボタン 2 のクリック関数によって例外がスローされたことのみを認識します。

zone.js

を導入した後、ボタン 2 のクリック関数によって例外がスローされることがわかっただけでなく、そのクリック関数がボタン 1 のクリック関数によってバインドされていることもわかり、さらに次のことがわかりました。最初のアプリケーションの起動は、main 関数によってトリガーされます。複数の非同期タスクを継続的に追跡するこの機能は、大規模で複雑なプロジェクトでは非常に重要です。次に、zone.js がそれをどのように実行するかを見てみましょう。 zone.js は、クリック イベントやタイマーなど、ブラウザーによって提供される非同期 API を引き継ぎます。このため、非同期操作に対するより強力な制御および介入機能を備え、より多くの機能を提供できます。ここで、クリック イベントを例として、それがどのように行われるかを見てみましょう。

Error: aw shucks
    at HTMLButtonElement.throwError ((索引):26:13)
    at ZoneDelegate.invokeTask (zone.js:406:31)
    at Zone.runTask (zone.js:178:47)
    at ZoneTask.invokeTask [as invoke] (zone.js:487:34)
    at invokeTask (zone.js:1600:14)
    at HTMLButtonElement.globalZoneAwareCallback (zone.js:1626:17)
    at ____________________Elapsed_571_ms__At__Mon_Jan_31_2022_20_09_09_GMT_0800_________ (localhost)
    at Object.onScheduleTask (long-stack-trace-zone.js:105:22)
    at ZoneDelegate.scheduleTask (zone.js:386:51)
    at Zone.scheduleTask (zone.js:221:43)
    at Zone.scheduleEventTask (zone.js:247:25)
    at HTMLButtonElement.addEventListener (zone.js:1907:35)
    at HTMLButtonElement.bindSecondButton ((索引):23:10)
    at ZoneDelegate.invokeTask (zone.js:406:31)
    at Zone.runTask (zone.js:178:47)
    at ____________________Elapsed_2508_ms__At__Mon_Jan_31_2022_20_09_06_GMT_0800_________ (localhost)
    at Object.onScheduleTask (long-stack-trace-zone.js:105:22)
    at ZoneDelegate.scheduleTask (zone.js:386:51)
    at Zone.scheduleTask (zone.js:221:43)
    at Zone.scheduleEventTask (zone.js:247:25)
    at HTMLButtonElement.addEventListener (zone.js:1907:35)
    at main ((索引):20:10)
    at ZoneDelegate.invoke (zone.js:372:26)
    at Zone.run (zone.js:134:43)

上記のコードでは、proto

EventTarget.prototype

を参照します。これは、このコード行が addEventListener 関数を再定義することを意味します。 makeAddListener 関数が何をするのかを見ていきましょう。 <pre class="brush:js;toolbar:false;">proto[ADD_EVENT_LISTENER] = makeAddListener(nativeAddEventListener,..)</pre>この関数は主に 2 つのことを行います。1 つはブラウザ自体がカスタム関数で提供する addEventListener 関数を実行すること、もう 1 つはクリック関数ごとにイベントを配置することです。 、これは、非同期 API に介入する

zone.js

の強力な機能の重要な要素でもあります。 ここで、この記事の冒頭の例に戻り、コンソールが完全な関数呼び出しスタックを出力できる理由を見てみましょう。 makeAddListener 関数を分析しました。この関数は、クリック関数ごとにイベント タスク (

zone.scheduleEventTask

関数の実行) を配置すると述べました。このスケジュール イベント タスク関数は実際に実行されます。 onScheduleTask:<pre class="brush:js;toolbar:false;">function makeAddListener() { ...... // 关键代码1 nativeListener.apply(this, arguments); ...... // 关键代码2 const task = zone.scheduleEventTask(source, ...) ...... }</pre>記事の冒頭でコンソールによって出力された完全な関数呼び出しスタックは、currentTask.data[creationTrace]# に保存されています。 # #内部は、LongStackTrace

インスタンスで構成される配列です。非同期タスクが発生するたびに、

onScheduleTask 関数は現在の関数呼び出しスタック ストレージを記録します。クラス LongStackTrace のコンストラクターを見てみましょう:

onScheduleTask: function (..., task) {
  const currentTask = Zone.currentTask;
  let trace = currentTask && currentTask.data && currentTask.data[creationTrace] || [];
  trace = [new LongStackTrace()].concat(trace);
  task.data[creationTrace] = trace;
}
this.error は関数呼び出しスタックを保存します。getStacktrace

関数は通常、

getStacktraceWithUncaughtError 関数を呼び出します。新しいエラー が表示されます。コールスタックが取得されます。 この記事では、zone.js の機能の一例を分析します。さらに多くの機能を知りたい場合は、公式ドキュメントを参照してください。この例を通じて、読者が zone.js

について一般的に理解できることを願っています。これは、Angular の変更検出に不可欠な基礎でもあるためです。この点については次の記事で説明します。

プログラミング関連の知識について詳しくは、プログラミング入門をご覧ください。 !

以上がAngular のzone.js とその仕組みの詳細な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.cnで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。