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的依赖:

image.png

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.

image.png

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 task

It 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的实现源代码:

image.png

相关文章
|
存储 缓存 JavaScript
Angular Universal 学习笔记
Angular Universal 学习笔记
|
前端开发 JavaScript API
Angular Change Detection 的学习笔记
Angular Change Detection 的学习笔记
|
存储 缓存 JavaScript
Angular Universal 学习笔记
Angular Universal 学习笔记
131 0
Angular Universal 学习笔记
|
JavaScript
Angular Form (响应式Form) 学习笔记
Angular Form (响应式Form) 学习笔记
184 0
Angular Form (响应式Form) 学习笔记
|
JSON API 数据格式
Angular CLI builder 学习笔记
Angular CLI builder 学习笔记
122 0
Angular CLI builder 学习笔记
|
JavaScript 测试技术 API
Angular library 学习笔记
Angular library 学习笔记
205 0
Angular library 学习笔记
|
设计模式 JavaScript 前端开发
Angular Lazy load(延迟加载,惰性加载) 机制和 feature module 的学习笔记
Angular Lazy load(延迟加载,惰性加载) 机制和 feature module 的学习笔记
344 0
Angular Lazy load(延迟加载,惰性加载) 机制和 feature module 的学习笔记
|
JavaScript 开发者
Angular 依赖注入学习笔记之工厂函数的用法
Angular 依赖注入学习笔记之工厂函数的用法
Angular 依赖注入学习笔记之工厂函数的用法
Angular Jasmine 里一些常用概念学习笔记 - describe, it, beforeEach的用法
describe: 定义一个test spec group,用来包裹多个specs,也称为suite:
Angular Jasmine 里一些常用概念学习笔记 - describe, it, beforeEach的用法
下一篇
无影云桌面