00:01
接下来我们继续的来介绍V的HMRAAPI,首先呢,我们先启动一下我们的项目,执行一下PPM run div,按照command单击,在浏览器里边打开我们当前的v basics检查,在控台上面我们看到fo works仍就被打印出来了,那么接下来我们再扩展一下accept这个API,我们打开man.JS,在这个if判断语句的里边,我们再去执行一下import.mett.hot.accept。我们这回不给这个accept方法传入参数了,它的语义呢,就是表示当前我们这个组件一旦发生变化的时候呢,它会执行我们当前组件的热更新,我们保存一下,写一个用例,我们在慢JS里边写一个console log一下man module保存一下。
01:00
我们发现呢,立刻执行了模块的热更新,在控台上面打印了慢猫九,如果我们在慢猫九的后面加一个点儿,大家发现又一次执行了热更新,这样的话呢,它就能够监测我们当前这个man.JS这个模块发生了变化,那接下来呢,我们再来讲解另外一个API,叫做dispose,我们得需要去设计一些代码,我们打开fo的JS,在这个代码里面,我们执行一个定时器,让它在控制台上面每过一秒打印一个数字,那一开始我们得需要去定义一个数字,我们可以定义一个变量,这个变量的名字呢,我们可以叫做catch,它是一个引用类型。在这里头我们再去定义一个amount这样的一个属性,后面的初始值呢为零。那么接下来呢,我们就可以使用set interval这个方法来去执行一个每隔一秒来去打印一个字符串或者打印一个数字这样的功能。我们在set里头去写一个函数,在函数题里头我们先做一个加一的动作,我们执行一下catch.amount加加,然后呢,我们再去打印一下呃,catch.amount。
02:16
然后我们让它每隔一秒以后执行这个函数,好我们保存一下,这样的话呢,我们在控制台上面就能看到每隔一秒它打印了我们这个数字加一的效果。接下来呢,我们做个实验来发现一个奇怪的现象,我们在f fowork的后面呢,加一个叹号,我先不保存文件,大家思考一下,如果我修改了当前那个拈,按理说这个拈呢,会重新的进行模块热更新,那热更新以后呢,它的基本的呃流程就是它会先把我们这个模块上一个代码给删除掉,然后呢再重新加载一批新的代码,这样的话呢,来实现一个模块的局部更新。那现在呢,我们来保存一下,我们看到的确是啊,这个foworks已经热更新了,但是你会发现两个定时器同时启动起来了,这是为什么呢?这是因为上一个定时器并没有被清理掉,那可见呢,这个定时器的操作是一个具有副作用的一个操作了,那也就是说我们在呃更新我们模块的时候,模块的上一个状态得需要把它的一些副作用函数的一些变量啊给清理掉,很显然呢,我们这个定时器是一个副作用函数,它没有被清理掉,所以呢,它又启动了一个新的定时器的同时,还保留了原来的定时器。
03:39
那怎么办呢?诶,我们得使用dispose这个方法来去做一个所谓的有副作用的一个一些状态的清理,那具体怎么办呢?我们现在在我们这个模块内部还得需要一个在开发环境里边的一个判断,首先呢,我们判断一下import.mett.hot是否存在,如果存在的话呢,我们就调一下import.might.hot的dispose这个方法,这个方法呢,只接收一个参数,这个参数呢是一个回调函数,这个回调函数在什么时候运行呢?就是在我们这个模块热更新的那个瞬间,它就会呃把我们的上一个模块清理的那个动作给记录下来,在清理的同时我我们可以去,呃在这里边去做一些具有啊清理副作用的这样的一些东西,那也就是说在模块状态发生变化的时候,我们就可以清理我们上一个呃模块的。
04:36
状态里边的一些呃内容了,比方说正好在这个模块热更新的时候,我们就可以清理我们定时器了,但是我们得需要给定时器加一个引用,这样的话我们才能清理它,所以呢,我们定一个变量叫做timer。然后呢,在这个里头我们进行一个判断,先看看timer是否存在,如果timer是存在的话,那我们就可以通过一个。
05:03
Interval来去清理啊,我一下我们的timer保存一下,然后我们再次刷新一下页面,然后重新的来去看看这个逻辑啊,是否正常的运行了,我们现在呢,执行了123456这样的一个累加的效果,那么接下来呢,我们去修改一下foworks,我们把这个叹号再去添加一个保存一下,大家发现fworks果然啊更新了,然后呢,我们这个定时器会重新的启动,因为我们再去更新模块的之前,我们已经把这个上一个定时器给清理掉了。好,那这个工作完成了以后呢,大家再思考一个问题,比方说我能不能在模块热更新的时候保留上一个amount的值呢?这样的话岂不更好?比如说我们的这个应用现在有一个状态,这个状态的话呢,我想在热更新的时候呢,还保留它,那我们可以做个实验,比方说我们还是拿amount为例,也就是说当我第二次去修改fwork的时候,我希望它的定时器重新启动,并且呢,它会从上一个计数的开始继续的记术,那这个功能的话,得需要我们去用一个data,就是hot里的data这个属性来去做一些所谓的状态的记录,怎么办呢?那我们可以基于现有的代码来继续的进行编写,我们可以呢去在判断一下当前的hott如果存在的情况下。
06:30
我们来去修改一下catch的这个值,我们让catch来去缓存我们的模块上一个状态的这个amount,首先呢,我们给catch来去重新的做个赋值,赋值为什么呢?它里的amount的值就等于import.ma.hot.data这个data的话呢,就是可以帮助我们缓存模块在状态发生变化的时候的一个公共的变量,或者是全局的状态,那它是个引用类型,后边呢,我们可以把catch给他。
07:04
那我们也可以把amount给读出来,这样的话就把我们当前代码里边的开始amount赋给了一个新的对象,这样的话相当于我们做了一个状态的保存,但是大家发现这里面暴露一个错误,说呢,你不能读取一个anti find的amount,很显然我们的catchche呢,一开始的时候可能是没有的,或者说我们至少啊还没有对它进行缓存,那怎么办呢?我们现在把这个data.catch给拷贝一下,然后我们做一个二次赋值,注意这个赋值我需要给大家解释一下,在原程GS里边这个赋值如果是两个同时赋值的话,它会把这个最终的值先付给catchche,再赋给第二个变量,那复制完了以后是不是就可以了呢?我们再保存发现还是有问题,我们再刷新页面,再看一下,还是刚才那个问题,这是因为在第一次的时候呢,我们这个import method hot data catch是没有值的,是为什么呢?因为我们的这个值的负值。
08:05
值是依托于我们这个计算,而这个计算的话还呃没有开始,那很显然呢,它是没有值的,而这一计算一旦来了以后呢,它会发现catch这个对象是没有的,因为呃,我们还没有对它进行赋值,所以呢,这里边我们得先去做一个判断,如果catch存在的话,我们再去读取这个catch下的amount。如果它不存在的话呢,我们就用零来赋值,这样的话才能保证啊,我们这个赋值是有效的,好,我们保存一下,现在再刷新一下页面,我们发现没有问题了,这个计数器呢,正常的在计数了,那么接下来我们来去验证一下这个catch是否真的有效了,这个catchche我们重新复制以后呢,下面仍旧是对这个缓存以后的catch进行累加,好了,那我们现在呢,再去,呃,更新一下fworks,我们在后面呢,加一个叹号保存一下。
09:02
好,我们发现果然fwork更新了,并且呢,这个呃计数器会从上一个数呃继续的进行计数,好这样的话,我们的这个hot的data这个属性也就理解了。最后呢,我们再去讲解另外两个API,一个是validate,一个是decline,那接下来我们在fo的后边呢,来去暴露一个变量,比方说我们来一个export,我们把这个catch给暴露出去,暴露出去以后呢,我们可以让它来实现更嗯丰富的功能,我们现在把fo.js先关闭掉,打开慢点GS我们实现一个什么功能呢?就是说这个new fo.fo这个方法的执行呢,不是当fo发生变化的时候它就执行,而是我们根据catch amount的数,然后看它具体的细节来去决定是否来去热更新。那接下来呢,我们把它去掉,然后呢,我们加一个判断,判断什么呢?因为刚才我们在fo的JS里边暴露了一个catch这样的变量,所以呢,我们就可以通过new fo拿到我们读取一下new fo的所谓的catch.amount如果这个值大于五的话,我们做件事情,如果小于五的话,我们再执行这个所谓的热更新,如果大于五的话,我就让页面刷新了,那刷新的话该怎么做呢?我们要执行一下import.ma.hot.invaliddate这样的一个方法,那这个方法的话呢,它会帮助我们去刷新啊,这个页面就不执行我们所谓的叫热更新了,我们来去做个实验,首先呢,我们现在再去刷新一下页面,打开fo的JS,然后呢,我们去修改一下这个works,我们加个叹号保存一下,大家发现现在是。
10:55
更新的,为什么呢?因为它没有大于五,因为正好是等于五的,那接下来呢,现在已经大于五了,我们再去更新一下,保存一下,大家发现页面刷新了,这是为什么呢?这是因为我们在里边加了一个判断,那么invalidate可以帮助我们刷新啊这个整个的页面了,那除了这个所谓的invalid这个方法API以外呢,还有一个API就是decline,它可以帮助我们让当前的这个模块立刻的执行,呃刷新啊,不执行热替换了,那accept可以执行热替换,那还有一个方法就是import.might.hot.decline。
11:37
这个方法呢,就是让我们这个模块刷新,那很显然跟accept是矛盾的,我们把它给注释掉,然后接下来我们来去试验一下,在f fo的JS里边我们再加个叹号,当这个模块发生变化的时候呢,我们的主模块肯定也发生变化,那它一到这里来的话,它肯定很显然不会执行刷模块的更新了,而是执行页面刷新了。好,现在我们回到fo的JS,我们保存一下,大家发现页面果然重新刷新了,好,这就是我们所有的API的讲解。
12:09
大家加油。
我来说两句