Angular zone学习笔记
https://blog.thoughtram.io/angular/2016/01/22/understanding-zones.html
假設有這三個函數:
foo(); bar(); baz();function foo() {...} function bar() {...} function baz() {...}要度量其運行時間:
var start,time = 0;timer = performance ? performance.now : Date.now;// start timer start = timer(); foo(); bar(); baz(); // stop timer time = timer() - start; // log time in ms console.log(Math.floor(time*100) / 100 + 'ms');然而,如果這些函數是異步執行的函數呢?那么下列的時間度量代碼,計算出來的duration就不準確了:
function doSomething() {console.log('Async task'); }// start timer start = timer(); foo(); setTimeout(doSomething, 2000); bar(); baz(); // stop timer time = timer() - start;什么是Angular的zone?
Zones can perform an operation - such as starting or stopping a timer, or saving a stack trace - each time that code enters or exits a zone. They can override methods within our code, or even associate data with individual zones.
zone可以在一段代碼進入或者離開一個zone的時候,執行一個操作,比如開啟或者關閉計時器,或者保存一個堆棧跟蹤。
Zones are actually a language feature in Dart.
Zone實際上是編程語言Dart的一個特性。Dart編譯之后的代碼也是JavaScript,所以我們可以直接在JavaScript里實現Zone的特性。
Angular項目里通常都有zone.js的依賴:
導入zone.js依賴之后,我們獲得了zone全局對象的訪問權。可以使用其run方法,將某個函數放入一個zone里執行:
function main() {foo();setTimeout(doSomething, 2000);bar();baz(); }zone.run(main);Zones can perform an operation each time our code enters or exits a zone.
支持fock操作:
var myZone = zone.fork();myZone.run(main);fock的時候可以指定一些參數,定制fock出來的zone的行為:
var myZoneSpec = {beforeTask: function () {console.log('Before task');},afterTask: function () {console.log('After task');} };var myZone = zone.fork(myZoneSpec); myZone.run(main);// Logs: // Before task // After task // Before task // Async task // After taskIt turns out that there are a few other hooks. In fact, those aren’t just hooks, but monkey-patched methods on the global scope.
全局scope里還存在稱為monke-patched的方法。
when we call setTimeout() we actually call Zone.setTimeout(), which in turn creates a new zone using zone.fork() in which the given handler is executed.
當我們調用setTimeout時,我們實際上調用的是Zone.setTimeout, 后者會使用zone.fork(),創建新的zone,而setTimeout里的函數,就運行在這個新fork出來的zone里面。
And that’s why our hooks are executed as well, because the forked zone in which the handler will be executed, simply inherits from the parent zone.
而hook執行兩次的原因,是因為函數運行于fork出來的zone里面,而后者繼承了parent zone的hook.
Zone.js重載了下列方法,并且以hook的方式提供給應用開發人員使用:
- Zone.setInterval()
- Zone.alert()
- Zone.prompt()
- Zone.requestAnimationFrame()
- Zone.addEventListener()
- Zone.removeEventListener()
We might wonder why methods like alert() and prompt() are patched as well. As mentioned earlier, those patched methods are hooks at the same time. We can change and extend them by forking a zone exactly the same way we did with beforeTask and afterTask. This turns out to be super powerful, because we can intercept calls to alert() and prompt() and change their behaviour when we write tests.
類似alert和prompt方法和其他方法一樣同時被patch,在fork一個新zone時,可以傳入我們自己的實現進去,在寫單元測試代碼時尤其有用。
用于度量一段異步執行代碼執行時間的profilingZone的實現源代碼:
var profilingZone = (function () {var time = 0,timer = performance ?performance.now.bind(performance) :Date.now.bind(Date);return {beforeTask: function () {this.start = timer();},afterTask: function () {time += timer() - this.start;},time: function () {return Math.floor(time*100) / 100 + 'ms';},reset: function () {time = 0;}}; }());使用方式:
zone.fork(profilingZone).fork({'+afterTask': function () {console.log('Took: ' + zone.time());}}).run(main);總結
以上是生活随笔為你收集整理的Angular zone学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 英雄联盟锐雯怎么打诺手(给英雄一个新的定
- 下一篇: hdcp功能是什么(hdmi中cec)