Angular zone学习笔记-阿里云开发者社区

开发者社区> -技术小助手-> 正文

Angular zone学习笔记

简介: 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



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


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


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
9637 0
Json.Net6.0入门学习试水篇
原文:Json.Net6.0入门学习试水篇 前言   JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。简单地说,JSON 可以将 JavaScript 对象中表示的一组数据转换为字符串,然后就可以在函数之间轻松地传递这个字符串,或者在异步应用程序中将字符串从 Web 客户机传递给服务器端程序。
1130 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
13363 0
1633
文章
0
问答
来源圈子
更多
+ 订阅
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载