最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

什么是 Zone ?

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

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

工作原理剖析

下面我們將通過(guò)一個(gè)示例來(lái)展示它的能力,并簡(jiǎn)單剖析一下背后的工作原理。

<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>

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

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

zone.js啟動(dòng)

但是如果我們通過(guò)zone.js啟動(dòng)運(yùn)行代碼,控制臺(tái)輸出會(huì)有什么不同呢,我們先調(diào)整啟動(dòng)代碼:

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

此時(shí)控制臺(tái)輸出如下:

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)

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

zone.js接管了瀏覽器提供的異步 API,比如點(diǎn)擊事件、計(jì)時(shí)器等等。也正是因?yàn)檫@樣,它才能夠?qū)Ξ惒讲僮饔懈鼜?qiáng)的控制介入能力,提供更多的能力。現(xiàn)在我們拿點(diǎn)擊事件舉例,看看它是如何做到的吧。

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

上述代碼中,proto便指的是EventTarget.prototype,也就是說(shuō)這行代碼重新定義了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ù),另外一個(gè)就是為每個(gè)點(diǎn)擊函數(shù)安排了一個(gè)事件任務(wù),這也是zone.js對(duì)異步 API 有強(qiáng)大介入能力的重要因素。

現(xiàn)在我們?cè)倩氐奖疚拈_(kāi)頭的示例中,看看控制臺(tái)為什么能夠輸出完整的完整的函數(shù)調(diào)用棧。剛剛我們分析過(guò)了makeAddListener函數(shù),其中提到它為每個(gè)點(diǎn)擊函數(shù)安排了一個(gè)事件任務(wù),也就是zone.scheduleEventTask函數(shù)的執(zhí)行。這個(gè)安排事件任務(wù)函數(shù)最終其實(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;
}

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

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

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

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

您可能感興趣的文章:

相關(guān)文章

  • AngularJS+Node.js實(shí)現(xiàn)在線聊天室

    AngularJS+Node.js實(shí)現(xiàn)在線聊天室

    隨著互聯(lián)網(wǎng)和信息技術(shù)的發(fā)展,如何快速構(gòu)建高效、強(qiáng)大的動(dòng)態(tài)網(wǎng)站成為很多人研究的熱點(diǎn)。該文將結(jié)合AngularJS和Node.js構(gòu)建一個(gè)在線聊天室,體現(xiàn)AngularJs和Node.js整合的優(yōu)點(diǎn)。
    2015-08-08
  • 使用Angular CLI生成 Angular 5項(xiàng)目教程詳解

    使用Angular CLI生成 Angular 5項(xiàng)目教程詳解

    這篇文章主要介紹了使用Angular CLI生成 Angular 5項(xiàng)目的教程詳解 ,需要的朋友可以參考下
    2018-03-03
  • angular中的http攔截器Interceptors的實(shí)現(xiàn)

    angular中的http攔截器Interceptors的實(shí)現(xiàn)

    本篇文章主要介紹了angular中的http攔截器Interceptors的實(shí)現(xiàn)的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2017-02-02
  • 使用Angular CLI從藍(lán)本生成代碼詳解

    使用Angular CLI從藍(lán)本生成代碼詳解

    這篇文章主要介紹了使用Angular CLI從藍(lán)本生成代碼詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-03-03
  • AngularJS過(guò)濾器filter用法總結(jié)

    AngularJS過(guò)濾器filter用法總結(jié)

    這篇文章主要介紹了AngularJS過(guò)濾器filter用法,結(jié)合實(shí)例形式較為詳細(xì)的總結(jié)分析了過(guò)濾器filter的功能、分類、使用技巧及自定義過(guò)濾器的實(shí)現(xiàn)方法,需要的朋友可以參考下
    2016-12-12
  • Angular.js跨controller實(shí)現(xiàn)參數(shù)傳遞的兩種方法

    Angular.js跨controller實(shí)現(xiàn)參數(shù)傳遞的兩種方法

    這篇文章主要給大家介紹了關(guān)于Angular.js跨controller實(shí)現(xiàn)參數(shù)傳遞的兩種方法,文中給出了詳細(xì)的介紹和示例代碼,相信對(duì)大家具有一定的參考價(jià)值,需要的朋友們下面來(lái)一起看看吧。
    2017-02-02
  • 詳解JavaScript的AngularJS框架中的表達(dá)式與指令

    詳解JavaScript的AngularJS框架中的表達(dá)式與指令

    這篇文章主要介紹了JavaScript的AngularJS框架中的表達(dá)式與指令,文中羅列了幾個(gè)常用的指令屬性加以說(shuō)明,需要的朋友可以參考下
    2016-03-03
  • AngularJS折疊菜單實(shí)現(xiàn)方法示例

    AngularJS折疊菜單實(shí)現(xiàn)方法示例

    這篇文章主要介紹了AngularJS折疊菜單實(shí)現(xiàn)方法,結(jié)合完整實(shí)例形式分析了AngularJS實(shí)現(xiàn)折疊菜單的具體步驟與相關(guān)操作技巧,需要的朋友可以參考下
    2017-05-05
  • angular4中引入echarts的方法示例

    angular4中引入echarts的方法示例

    這篇文章主要介紹了angular4中引入echarts的方法示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-01-01
  • angular將html代碼輸出為內(nèi)容的實(shí)例

    angular將html代碼輸出為內(nèi)容的實(shí)例

    今天小編就為大家分享一篇angular將html代碼輸出為內(nèi)容的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-09-09

最新評(píng)論

榆社县| 东平县| 大新县| 山东| 石门县| 皮山县| 景德镇市| 陕西省| 磐石市| 惠安县| 临朐县| 恩施市| 安阳市| 建湖县| 苏尼特右旗| 微博| 福海县| 秦安县| 桑日县| 咸阳市| 邢台县| 通城县| 宿迁市| 潜山县| 宜昌市| 衢州市| 南华县| 浦县| 黔西| 新丰县| 自贡市| 台前县| 磐安县| 兴业县| 饶平县| 调兵山市| 探索| 乐业县| 宁晋县| 临猗县| 建湖县|