欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Angular異步執(zhí)行學習之zone.js使用

 更新時間:2023年06月26日 17:11:41   作者:Zuckjet  
這篇文章主要為大家介紹了Angular異步執(zhí)行學習之zone.js使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

什么是 Zone ?

或許你聽說過 Angular 使用了zone.js, 但 Angular 為什么要使用zone.js, 它能夠提供哪些功能呢?今天我們單獨寫一篇文章聊聊zone.js,關(guān)于它在 Angular 框架中發(fā)揮的作用將在下一篇文章講述。

什么是 Zone ? 官方文檔是這么解釋的:Zone 是一個跨多個異步任務的執(zhí)行上下文。一句話總結(jié)來說,Zone 在攔截或追蹤異步任務方面有著特別強大的能力。

工作原理剖析

下面我們將通過一個示例來展示它的能力,并簡單剖析一下背后的工作原理。

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

這是一個簡單的 HTML 頁面。頁面加載時會給第一個按鈕添加點擊事件,其點擊事件函數(shù)的功能是給第二個按鈕添加點擊事件,而第二個按鈕的點擊事件函數(shù)功能是拋出一個異常。我們依次點擊第一個按鈕和第二個按鈕,控制臺顯示如下:

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

zone.js啟動

但是如果我們通過zone.js啟動運行代碼,控制臺輸出會有什么不同呢,我們先調(diào)整啟動代碼:

Zone.current.fork(
      {
        name: 'error',
        onHandleError: function (parentZoneDelegate, currentZone, targetZone, error) {
          console.log(error.stack);
        }
      }
    ).fork(Zone.longStackTraceZoneSpec).run(main);

此時控制臺輸出如下:

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)

通過對比我們知道:不引入zone.js時,我們通過錯誤調(diào)用棧僅僅能夠知道,異常是由按鈕2的點擊函數(shù)拋出。而引入了zone.js后,我們不僅知道異常是由按鈕2的點擊函數(shù)拋出,還知道它的點擊函數(shù)是由按鈕1的點擊函數(shù)綁定的,甚至能夠知道最開始的應用啟動是main函數(shù)觸發(fā)。這種能夠持續(xù)追蹤多個異步任務的能力在大型復雜項目中異常重要,現(xiàn)在我們來看zone.js是如何做到的吧。

zone.js接管了瀏覽器提供的異步 API,比如點擊事件、計時器等等。也正是因為這樣,它才能夠?qū)Ξ惒讲僮饔懈鼜姷目刂平槿肽芰?,提供更多的能力。現(xiàn)在我們拿點擊事件舉例,看看它是如何做到的吧。

proto[ADD_EVENT_LISTENER] = makeAddListener(nativeAddEventListener,..)

上述代碼中,proto便指的是EventTarget.prototype,也就是說這行代碼重新定義了addEventListener函數(shù)。

makeAddListener函數(shù)

我們繼續(xù)看看makeAddListener函數(shù)做了什么。

function makeAddListener() {
  ......
  // 關(guān)鍵代碼1
  nativeListener.apply(this, arguments);
  ......
  // 關(guān)鍵代碼2
  const task = zone.scheduleEventTask(source, ...)
  ......
}

該函數(shù)主要做了兩件事,一是在自定義函數(shù)中執(zhí)行瀏覽器本身提供的addEventListener函數(shù),另外一個就是為每個點擊函數(shù)安排了一個事件任務,這也是zone.js對異步 API 有強大介入能力的重要因素。

現(xiàn)在我們再回到本文開頭的示例中,看看控制臺為什么能夠輸出完整的完整的函數(shù)調(diào)用棧。剛剛我們分析過了makeAddListener函數(shù),其中提到它為每個點擊函數(shù)安排了一個事件任務,也就是zone.scheduleEventTask函數(shù)的執(zhí)行。這個安排事件任務函數(shù)最終其實執(zhí)行的是onScheduleTask:

onScheduleTask: function (..., task) {
  const currentTask = Zone.currentTask;
  let trace = currentTask && currentTask.data && currentTask.data[creationTrace] || [];
  trace = [new LongStackTrace()].concat(trace);
  task.data[creationTrace] = trace;
}

文章開頭控制臺輸出的完整的函數(shù)調(diào)用棧,存儲在currentTask.data[creationTrace]里面,它是一個由LongStackTrace實例組成的數(shù)組。每次有異步任務發(fā)生時,onScheduleTask函數(shù)便把當前函數(shù)調(diào)用棧存儲記錄下來,我們看看類LongStackTrace的構(gòu)造器就知道了:

class LongStackTrace {
    constructor() {
        this.error = getStacktrace();
        this.timestamp = new Date();
    }
}
function getStacktraceWithUncaughtError() {
    return new Error(ERROR_TAG);
}

this.error存儲的便是函數(shù)調(diào)用棧,getStacktrace函數(shù)通常調(diào)用的是getStacktraceWithUncaughtError函數(shù),我們看到 new Error大概就能夠知道整個調(diào)用棧是如何得來的了。

本文分析的只是zone.js能力的一個示例,如果你希望了解更多功能可以參閱官方文檔。通過這個示例,希望讀者能對zone.js有一個大概的認識,因為它也是 Angular 變更檢測不可或缺的基石,更多關(guān)于Angular異步執(zhí)行zone的資料請關(guān)注腳本之家其它相關(guān)文章!

您可能感興趣的文章:

相關(guān)文章

  • 淺析AngularJS中的指令

    淺析AngularJS中的指令

    指令(Directives)是所有AngularJS應用最重要的部分。盡管AngularJS已經(jīng)提供了非常豐富的指令,但還是經(jīng)常需要創(chuàng)建應用特定的指令
    2016-03-03
  • Angular的MVC和作用域

    Angular的MVC和作用域

    本文主要Angular的MVC和作用域進行詳細分析介紹,具有一定的參考價值,下面跟著小編一起來看下吧
    2016-12-12
  • AngularJS ng-app 指令實例詳解

    AngularJS ng-app 指令實例詳解

    本文主要介紹AngularJS ng-app 指令,這里整理了ng-app指令的一些資料,并附實例代碼,有需要的小伙伴可以參考下
    2016-07-07
  • Angular實踐之將Input與Lifecycle轉(zhuǎn)換成流示例詳解

    Angular實踐之將Input與Lifecycle轉(zhuǎn)換成流示例詳解

    這篇文章主要為大家介紹了Angular實踐之將Input與Lifecycle轉(zhuǎn)換成流示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-02-02
  • AngularJS利用Controller完成URL跳轉(zhuǎn)

    AngularJS利用Controller完成URL跳轉(zhuǎn)

    本文的主要內(nèi)容是介紹在AngularJS中怎樣利用Controller實現(xiàn)URL跳轉(zhuǎn),本文給出了實例代碼,簡單明了,有需要的可以參考學習。
    2016-08-08
  • Angular.js中定時器循環(huán)的3種方法總結(jié)

    Angular.js中定時器循環(huán)的3種方法總結(jié)

    這篇文章主要給大家總結(jié)了angular.js中定時器循環(huán)的3種方法,分別是利用$interlval實現(xiàn)、$timeout的遞歸調(diào)用來實現(xiàn)以及$timeout借助arguments.callee來實現(xiàn),每種方法都給出了詳細的示例艾瑪供大家學習參考,需要的朋友們下面跟著小編一起來學習學習吧。
    2017-04-04
  • Angular 數(shù)據(jù)請求的實現(xiàn)方法

    Angular 數(shù)據(jù)請求的實現(xiàn)方法

    本篇文章主要介紹了Angular 數(shù)據(jù)請求的實現(xiàn)方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05
  • Angular5中調(diào)用第三方js插件的方法

    Angular5中調(diào)用第三方js插件的方法

    下面小編就為大家分享一篇Angular5中調(diào)用第三方js插件的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-02-02
  • Angular X中使用ngrx的方法詳解(附源碼)

    Angular X中使用ngrx的方法詳解(附源碼)

    ngrx是一套利用RxJS的類庫,下面這篇文章主要給大家介紹了關(guān)于Angular X中使用ngrx的方法,文中通過示例代碼介紹的非常詳細,對大家具有一定的參考學習價值,需要的朋友們下面來一起看看吧。
    2017-07-07
  • AngularJS學習筆記之TodoMVC的分析

    AngularJS學習筆記之TodoMVC的分析

    這篇文章主要介紹了AngularJS學習筆記之TodoMVC的分析的相關(guān)資料,需要的朋友可以參考下
    2015-02-02

最新評論