加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

学习ng2,从zonejs开始(非官方翻译) ----angular2系列(一)

发布时间:2020-12-17 10:38:14 所属栏目:安全 来源:网络整理
导读:: 官方解释: zone.js为JavaScript提供了执行上下文,可以在异步任务之间进行持久性传递。 最开始我一直没理解到这句话,学习过程中我也因为自己的一些失误而一直纠结徘徊,情况是这样的: 首先我在本地用npm安装了zone.js,然后我就打开了zone.js的github

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

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

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

这一切都很正常,然后看着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(= setTimeout(<span style="color: #0000ff;">function<span style="color: #000000;"> () {
console.log(
'in the zone 1: ' + !!<span style="color: #000000;">zone.inTheZone);
},
0<span style="color: #000000;">);
});

console.log('in the zone 2: ' + !!<span style="color: #000000;">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(= '1: ' + !!'2: ' + !!0'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,结果如下:

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

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

zone还提供了

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

demo如下:

profilingZone = ( time = 0= performance ?"beforeTask".start ="afterTask"+= timer() - Math.floor(time*100) / 100 + 'ms'= 0 zone.fork(profilingZone).run(</span><span style="color: #0000ff;"&gt;function</span><span style="color: #000000;"&gt;(){ console.log(profilingZone.time()); setTimeout(</span><span style="color: #0000ff;"&gt;function</span>(){console.log(profilingZone.time())},200<span style="color: #000000;"&gt;); });/***console***///</span>beforeTask//0ms//afterTask//beforeTask//<em id="__mceDel" style="line-height: 1.5;"&gt;<em id="__mceDel"&gt;<em id="__mceDel"&gt;<em id="__mceDel"&gt;<em id="__mceDel"&gt;<em id="__mceDel"&gt;<em id="__mceDel"&gt;1.8ms//</em></em></em></em></em></em></em><em id="__mceDel" style="line-height: 1.5;"&gt;<em id="__mceDel"&gt;<em id="__mceDel"&gt;<em id="__mceDel"&gt;<em id="__mceDel"&gt;<em id="__mceDel"&gt;<em id="__mceDel"&gt;<em id="__mceDel"&gt;<em id="__mceDel"&gt;afterTask</em></em></em></em></em></em></em></em></em></pre>

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

zoneJs官网已经不推荐0.5版本了,但是

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

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

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

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

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

当然这篇博客还是参考了,破狼的文章?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读