00:00
大家好,我是上硅谷H5学科讲师,我叫闫志勇。在程序员节日到来之际,由我来给大家分享几道面试题,本次主要分享的内容为红任务和微任务。那我们先来看一下什么是红任务,什么是微任务。好,那首先。在讲红任务和微任务之前呢,啊,需要大家了解几个知识点,比如说我们GS世界腾巡机制。以及GS是单线程的。那相信大家对这方面的知识应该是有所了解的,第一个我们GS是单线程的,所以我们可以叫它为主线程,而我们的GS代码呢,都是在主线程上执行的。只不过是我们又要区分它是同步执行还是异步执行。当你的。
01:06
代码是异步的话,那么它对应的就应该有一个东西叫回调函数。而不同的任务对应着不同的回调,比如说我们定时器的回调,还有呃,发送价请求的回调,以及我们对应事件的回调,比如说点击事件。那么这些不同的回调函数呢?又会被交给不同的模块去管理,比如说我们的定时器模块以及网络请求模块,以及事件处理模块。那么我们的回调什么时候执行,首先要取决于这些模块什么时候将回调函数放入到哪,放入到我们的事件队列里边,哎,我们又叫它EQ。
02:00
放入到世界队列里边还不够,那么GS引擎会通过龙形的方式呢,去询问这个世界队列是否有可执行的回调,如果说有呢,就会将这个函数勾出去,勾到主线程上去执行。这也就是为什么回调函数被大家称为钩子函数的一个原因。好,如果说大家理解了这一方面的知识以后,我们接着来看什么是红任务,什么是微任务,首先红任务呢,它分类,那么在这里边我们常见的比如说set out set interval以及。新推出来一个属性叫request,那这个属性呢,是window的属性叫request animation frame,哎,这个呢是用于告诉,提前告诉浏览器我们将要在下一次进行动画之前帮我们调用对应的回调函数,好,那么这些任务都都首先他们都是义务任务,而。
03:09
在他们是义务任务的同时呢,又属于红任务。那我先说一下分类,那微任务有哪些呢?V任务,比如说我们另一个promise对象,我们是不是会生成一个实例啊,那么实例方法对应的有个Z,这里边呢,有一个有两个回调函数,那么这两个回调呢,其实就属于微任务,包括对node了解的同学呢,可能知道node里边。有一个叫pro,有个叫next tick的回调,那么这个呢,就属于是任务队列里面的任务。哎,至于说为什么这样分,那就是人家GS引擎当初在定义的时候已经分好了。
04:04
好,那分了这些有什么用呢?哎,有什么用呢?那接下来给大家去定义一下。什么是红任务?嗯,什么是红任务?那么红任务是被放置任务队列,红任务队列里边的任务就叫红任务,当然了,我们说的微任务呢,就是被放到哪,放到微任务世界队列里边,哎,微任务世界队列里边。那当我的GS代码要执行的时候,哎,也是我们GS主线程上的代码要执行的时候,就相当于是启动了我们第一个红任务,哎,第一个红任务我先给大家说一下。刚我们说。红任务。所处的队列就是红任务队列。红任务队列,那么红任务队列里边。
05:08
第一个红肉队列中。执有一个任务,哎,就是干嘛执行我们全局,或者说是执行主线程上的GS代码,那么这是第一个活任务队列,哎,当我说了第一个是不是也就是意味着它有第二个,第三个呀,哎,在这儿我要强调一下,红任务队列可以有多个,可以有多个好我们对比来看。对比值来看。那什么是微任务能。微任务队列,或者说微任务所处的队列就是微任务队列,微任务队列比较特殊,它呢只有一个微任务队列,而且呢,它的它是微任务队列里面的任务什么时候执行呢?他呢在。
06:20
上一个应该是上一个红任务队列执行完毕,哎后,如果有微任务,就如果有微任务队列就会执行。微任务队列中的所有任务,好,以上呢是对红润和微任务的一些定义,哎,一些定义那。这个时候呢?我们来看一道比较经典的面试题。
07:01
好,我把这个代码贴过来,大家可以看一下,那么。这个。这一个,这是我们代码的起始位置和结束位置,而里边呢,有一个延时定时器,只不过当前延时的时间是零秒,那紧接着再往下呢,是new了一个promise对象。好。在这个new的回调,在这个new promise这个函数里边呢,我们有一个放循环,然后呢,我去执行了一下resolve,哎,相信大家都能理解,这一步的作用呢,是修改promise实力对象的状态,没成功的状态。那紧接着再往下呢,这有点任能里面呢,我只写了一个回调,那本质原因是因为上边这我调用的是,所以呢肯定会执行第一回调,那么第二个失败的回调呢,我就没有再再去写它。好,那根据我们以上的这些描述呢,咱们来分析一下它输出的结果以及顺序到底是什么样的,那首先上来第一个肯定是它,这没有任何问题,紧接着再往下我们来看在这一块。
08:18
哎,有一个延时定时器,那虽然说它设定的时间是零秒,但延时定时器呢,它对应的是一个回调,也就是说不是立即执行。再通过我刚刚的讲解,我们发现延时定时器呢是属于一个红任务,也就是说该任务会被放到红任务队列里面。红任务队列里边,那这个时候我们大概的来画一下,好,那在这儿呢,我呢去打开我们对应的画图工具。首先上来我们说了,有一个叫。
09:00
哎,把这个线呢调的细一点上来有一个队列叫红任务队列,好红任务队列,那么该队列呢,有且只有一个任务是什么呢?就是执行GS主线程上的代码,好,那在这个里面呢,我们写一下。本次的任务是执行主线程上的。代码。好,那么这是一个红任务队列,哎,这是一个红任务队列。那么在执行的过程中,我们发现了有一个延时定时器,哎,它对应的是不是应该又是一个红任务啊。那么这个时候呢?他应该被放到红任务队列里边,哎,大家看我刚说了,第一个红任务队列只有一个任务,也就是说我们新产生的红任务应该干嘛呀,哎,他应该呢又创建一个。
10:01
红任务队列,又创建一个宏任务队列,好在这儿呢,我们写一下,那这个呢应该是,那这个呢应该是第二个。红任务队列,红任务队列里边要挨个去放置任务,那首先放置呢,就是我们刚刚看到那个叫sat。Time out,任务好,放到。第二个活任务队列里面,紧接着再往下走另一个promise。我们都知道另一个,那这属于是同步。任务当new的同时,我是不是要执行里面的放循环,那其实这个放循环呢,也相当于是主线程上立马要执行的代码,那毫无疑问,紧接着他是不是应该去打印这个I的值啊,哎,每一次进来的话应该是什么?应该是12345对吧。
11:03
好,没有问题,那在这个之后,这儿是不是要执行一个resolve呀,Resolve一旦被调用,它会立马去调用这个认的方法,只不过是认为要检测我当时promise实例对象的状态是成功还是失败,来决定调用它里边的哪个回调,对吧?那现在他的状态是不是成功的,所以我按理来说是不是应该去调用这个回调啊。只不过是我们刚说了。New promise点任,这里面的回调呢属于什么?属于微任务,那么既然是微任务,它是不是对应的应该有一个队列叫。微任务队列,哎,应该叫微任务队列,好,那既然有一个微任务队列了,我们是不是应该把对应的任务放进去啊,那此时对应的任务应该是利用这个promise,哎,它实例里边那个任对应的回调对吧。
12:14
第呢比较小,那这个时候呢,我给它换一行来换行来把这个往这边去挪一下,好,那放到了微任务队列里面以后,我们紧接着再往下看。放进去以后,我继续往下走,它是不是要执行主线程上的代码,因为它的优先级是最高的,好,那么也就是说。这是第一个,刚刚放循环的打印是第二个,那紧接着再往下,这是吧,相当于是第三个呀。哎,刚刚这两个我们也说了,但是我为什么没有提到它呢?因为呢,它不是立即执行的,分别被放到了两个队列里边,好当我主线程上的代码执行完以后,注意,也就是说当这个执行完了以后,我们再一看是不是有两个队列呀,有两个队列,那么这个时候应该去执行哪个队列里面的任务呢?
13:17
哎,在这儿我要强调一下。当我们也是,我在这儿可以去补充一下当红任务队列哎中的任务。全部执行完以后,会查看是否有微任务。对不对,如果有限执行。微任务队列中的所有任务,如果没有呢?去啊,如果没有。
14:03
就查看是否有,这应该是是否有红任务队列,红任务队列那通过我以上的描述,大家应该能猜到,当我一个红任务队列执行完,他会去看是否有微任务队列,哎,微任务队列如果说有呢,我先执行微任务队列中的所有任务,只有他执行完了以后,我才会接着去执行什么下一个活任务队列里面的任务,所以呢,当我主线程上这个cons.log and执行完以后。他应该是先去执行谁啊是不promise实实力认的方法中回调也就应该是先打印他。只有他执行完了,那么当前活任务队列里边是不是没有其他的任务了,所以呢,再去执行第二个活任务队列中的set time out啊,通过我们以上的分析呢,那这个set out它应该是最后一个被输出的。
15:11
好,那这个时候呢,我们打开浏览器来看一下,是不是这样的,好,现在呢,我打开浏览器来到控制台打印,我们看一下诶。第一个是不是start,第二个。第二个这哦,刚刚口误,刚刚这咱们这儿起始的放循环这是零,所以呢,它的输出是不是01234,因为我这是不是小于五啊好,那这个没有问题,那紧接着再往下的话,执行的是哪个,是不是这个and呀,好再往下promise实例执行,再往下呢是定时器。好,那这样的话呢,我们就把这个红任务以及微任务呢给大家讲清楚了,如果说大家想了解更详细的资料,可以访问上硅谷的官网,好,那么本节课呢就到这儿。
我来说两句