Zone是什么:

  官方解释:zone.js为JavaScript提供了执行上下文,可以在异步任务之间进行持久性传递。

最开始我一直没理解到这句话,学习过程中我也因为自己的一些失误而一直纠结徘徊,情况是这样的:

  首先我在本地用npm安装了zone.js,然后我就打开了zone.js的github ———— zoneJs

这一切都很正常,然后看着readme,跟着demo写下去。下面这样:

然后问题来了,当我运行的时候,结果根本就不是官方显示的那样,我打开调试器,发现全局根本没有 window.zone ,却只有window.Zone,

难道是需要new一个?好吧,我new一个。结果还是不对。 好吧,我去看源码,发现原型根本就没有beforeTask,afterTask,而后看了很久源码,

发现run和fork方法的执行逻辑, 根本就不像是官方教程那样。

最后我终于找到问题了:

是版本问题,我看的教程是0.5版本,看的源码确是0.6,本地安装的版本也是默认最新的0.6。

好吧,我承认我英文不好,没看到DEPRECATED 这个单词。

安装0.5,那么这个问题解决了。以后小心...

言归正传, 我们在demo中去理解:

zone.fork().run(function () {
zone.inTheZone = true; setTimeout(function () {
console.log('in the zone 1: ' + !!zone.inTheZone);
}, 0);
}); console.log('in the zone 2: ' + !!zone.inTheZone); //console
//'in the zone 2: false'
//'in the zone 1: true'

在demo的基础上,我加上了数字编号 'in the zone ' + '1' or '2',  当然他们的执行顺序,没什么问题。问题就是为什么第一次输出是false?

执行run的时候,zone.inTheZone已经变成true了,这个全局对象的属性应该已经是true了啊!

readme下面还有一句话:Note that the function delayed by setTimeout stays inside the zone

延迟方法已经停留在zone内部,这是什么意思?这时候我又改变了一下代码:

zone.fork().run(function () {
zone.inTheZone = true;
console.log(zone);
console.log('1: ' + !!zone.inTheZone);
setTimeout(function () {
console.log(zone);
console.log('2: ' + !!zone.inTheZone);
}, 0);
});
console.log(zone);
console.log('3: ' + !!zone.inTheZone);

结果:

注意zone的 id , 全局zone原来一直在变化, 他们的父子关系是如下:父->子,id:1 -> id:2 -> id:3

全局zone最开始默认id为1。

zone.fork.run的时候,zone就创建了一个新zone任务,id为2

执行setTimeout的时候,又创建了一个id为3。

不管运行什么任务,其实全局zone都在变化,所有任务都在全局zone下执行了。

这就是官方说的:zone.js采用猴子补丁(Monkey-patched)的暴力方式将JavaScript中的异步任务都包裹了一层,使得这些异步任务都将运行在zone的上下文中。

好吧,虽然说zone在变化,为什么第一次输出是false,现在解释可能就简单的多了。还得看下源码:

源码告诉我们:在执行当前zone任务的时候,全局zone指向当前任务的zone对象,执行完毕后全局zone还原到前一个zone任务。

那么,执行run的时候,全局zone是id2的任务,执行完毕后 id2的zone的inTheZone属性变成true,全局zone又变成id1的zone对象,

而后马上输出了 id1 的 inTheZone 属性,这个时候 id1 并没有定义inTheZone,所以是false。

最后执行了 id3 的任务,为什么又输出是true呢,现在只有 id2 的 inTheZone 才会是true啊!

原因是zone会继承父zone,如图:

这样这个输出结果为什么是这样就算搞清楚了。

但是它又是如何给setTimeout添加zone任务的呢,因为run执行时并没有办法执行延迟操作,异步操作会被添加到浏览器的事件队列,在下一次事件循环(event loops)中才会被执行。

setTimeout怎么被zone给捕获的呢。这也是zoneJs比较核心的一个地方:

zone修改了原生setTimeout,我们在控制器里输入setTimeout,结果如下:

function() {
return global.zone[setName].apply(global.zone, arguments);
}

当然被修改的还有下面这些延迟事件(截图自源码):

所有延迟事件都将被zone捕获。

zone还提供了执行前后的钩子函数(hook):

  • onZoneCreated:产生一个新的zone对象时的钩子函数。zone.fork也会产生一个继承至基类zone的新zone,形成一个独立的zone上下文;
  • beforeTask:zone Task执行前的钩子函数;
  • afterTask:zone Task执行完成后的钩子函数;
  • onError:zone运行Task时候的异常钩子函数;

demo如下:

var profilingZone = (function () {
var time = 0,
timer = performance ?
performance.now.bind(performance) :
Date.now.bind(Date);
return {
beforeTask: function () {
console.log("beforeTask");
this.start = timer();
},
afterTask: function () {
console.log("afterTask");
time += timer() - this.start;
},
time: function () {
return Math.floor(time*100) / 100 + 'ms';
},
reset: function () {
time = 0;
}
};
}()); zone.fork(profilingZone).run(function(){
console.log(profilingZone.time());
setTimeout(function(){console.log(profilingZone.time())}, 200); }); /***console***/
//beforeTask
//0ms
//afterTask //beforeTask
//1.8ms
//
afterTask

这些钩子函数能帮助我们,任务前后拦截并做一些想要的操作,不管是延迟或不延迟的任务都将被拦截。

zoneJs官网已经不推荐0.5版本了,但是zone0.6几乎算没有文档。

readme上的: See the new API here

打开这个here,看起来确实也很难理解

zonejs 0.6改动较大,封装性很强,写法变化较大,还有待研究

目前ng2已经在升级0.6了,最终修改完毕后,到底会是什么样子,还不得知,目前我看到的0.6的源码里,好像已经没有beforeTask这些钩子函数了。

总之0.6的代码太难以理解了。我没怎么看懂,它可以做什么。

目测ng2要发布正式版,还需要时间。

当然这篇博客还是参考了,破狼的文章 zone.js - 暴力之美

非常感谢他为ng社区做出的贡献!

学习ng2,从zonejs开始(非官方翻译) ----angular2系列(一)的更多相关文章

  1. ng1和ng2的部分对比----angular2系列(四)

    前言: angular2相比angular1做了革命性的改变.对于开发者来说,我们知道它框架的实现上改变极大.我们看到代码也能发现它写法上变化很大,似乎完全是另一个东西. 但是当我们真正去写下去的时候 ...

  2. angular2系列教程(九)Jsonp、URLSearchParams、中断选择数据流

    大家好,今天我们要讲的是http模块的第二部分,主要学习ng2中Jsonp.URLSearchParams.observable中断选择数据流的用法. 例子

  3. angular2系列教程(一)hello world

    今天我们要讲的是angular2系列教程的第一篇,主要是学习angular2的运行,以及感受angular2的components以及模板语法. 例子 这个例子非常简单,是个双向数据绑定.我使用了官网 ...

  4. angular2系列教程(十)两种启动方法、两个路由服务、引用类型和单例模式的妙用

    今天我们要讲的是ng2的路由系统. 例子

  5. ng2响应式表单-翻译与概括官网REACTIVE FORMS页面

    本文将半翻译半总结的讲讲ng2官网的另一个未翻译高级教程页面. 原文地址. 文章目的是使用ng2提供的响应式表单技术快速搭出功能完善丰富的界面表单组件. 响应式表单是一项响应式风格的ng2技术,本文将 ...

  6. ISO/IEC 9899 C语言标准(非官方翻译)

    本系列博文将以ISO/IEC 9899最新的官方手册为准,然后再添加GCC以及Clang编译器对标准的扩展. 本系列博文将不仅仅是针对C编程语言(C Programming Language)标准的翻 ...

  7. openPOWERLINK开源POWERLINK协议栈说明文档中文非官方翻译

    GitBook分享,翻译进行中:https://winshton.gitbooks.io/openpowerlink-stack-cn/content/

  8. (23)unity4.6学习Ugui中国文档-------非官方Demo1

    大家好,我是广东太阳.   转载请注明出处:http://write.blog.csdn.net/postedit/38922399 更全的内容请看我的游戏蛮牛地址:http://www.unitym ...

  9. 开始进行lammps手册的学习啦,跟着Manual一边翻译一边做吧!(转载)

    转载自:http://blog.sina.com.cn/s/blog_64813e370100ngsz.html 注明:黄色部分基本上为不懂的部分,红色字体为所做注释 一.各种文件的介绍: 1 in ...

随机推荐

  1. day9---多线程,线程锁,队列

    进程.线程 http://www.ruanyifeng.com/blog/2013/04/processes_and_threads.html 使用threading模块实现多线程编程[综述] Pyt ...

  2. 在 Vagrant 下启用 SMB 文件共享

    在使用 vagrant 搭建 php 开发环境的时候,需要用到文件同步同步功能.在比对了众多网络文件系统之后,发现对 Windows 下文件同步系统最友好的是 smb, 那么怎么在 vagrant 启 ...

  3. 快速学习C语言四: 造轮子,ArrayList

    高级语言里的列表是最常用的数据结构,在C里造个轮子玩玩,C没有泛型,先用int练习. Collection的ADT一般有hasnext,next,add, remove操作,List一般还加了remo ...

  4. HTML5按钮的点击态问题

    开始在网页上实现点击态是mousedown mouseup来实现但是手机HTML5实现点击态怎么就不可以了呢 经过查资料才知道手机浏览器来实现点击态是通过 touchstart touchend实现

  5. ASP.NET 开发必备知识点(2):那些年追过的ASP.NET权限管理

    一.前言 在前一篇文章已经为大家介绍了OWIN和Katana,有了对他们的了解之后,才能更好地去学习Asp.net Identity,因为Asp.net Identity的实现集成了Owin.其实在A ...

  6. Java IO7:管道流、对象流

    前言 前面的文章主要讲了文件字符输入流FileWriter.文件字符输出流FileReader.文件字节输出流FileOutputStream.文件字节输入流FileInputStream,这些都是常 ...

  7. Python3实现TCP端口扫描器

    本文来自 高海峰对 玄魂工作室 的投稿 作者:高海峰 QQ:543589796 在渗透测试的初步阶段通常我们都需要对攻击目标进行信息搜集,而端口扫描就是信息搜集中至关重要的一个步骤.通过端口扫描我们可 ...

  8. Unity3D热更新全书-PageZero

    由于深刻的认识到自己是个思维跳跃的人,深入浅出是个我还要努力很久的目标,为了让大家不至于在我乱七八糟的文字中迷失,特整理目录一份 无分类 <Unity3D热更新全书-何谓热更新,为何热更新,如何 ...

  9. iOS Crash常规跟踪方法及Bugly集成运用

    当app出现崩溃, 研发阶段一般可以通过以下方式来跟踪crash信息 #1.模拟器运行, 查看xcode错误日志 #2.真机调试, 查看xcode错误日志 #3.真机运行, 查看device系统日志 ...

  10. 关于redis启动流程介绍

    转载于:http://www.itxuexiwang.com/a/shujukujishu/redis/2016/0216/94.html?1455870894 1. 准备运行环境 * 设置oom h ...