【吊打面试官系列】打通你的前端事件轮询“八门”

199 阅读3分钟

说在前面:学习肯定不是为了吊打谁,笔者想表达的是知识越扎实,人就越自信。很多同学在面试之前或者在面试过程中总有怯场的情绪,不能把自己最自信,最有实力的一面表现出来。可以和笔者一样试着保持一种想要“吊打面试官”的情绪去学习与准备,在面试中也能保持这种情绪从容的应对问题,避免紧张情绪导致的失误而悔恨。

偶哈呦,大噶好,笔者来更新“吊打面试官”系列了。笔者现在想把这个系列一周一更新,基本覆盖前端面试中的热门知识点,希望能让各位读者老爷能在快乐中获得些许收获,有收获的话请不要吝啬你的赞和关注哦。

(怎么又是面试题?不能有点深度吗?)

-。-笔者现在是应届生,深不了一点,主要是想让自己养成写博客的习惯,后面肯定会深起来的!

废话不多说,开始本章的面试官对话吧!

面试官:说说你对事件轮询的认识!

小白:js是单线程的语言为了解决耗时很长的任务长期占用线程的问题,引出了异步任务的概念。同步任务放在任务队列中,异步任务放在消息队列中。然后按照事件轮询的原则来执行任务:首先执行任务队列中的同步任务,当同步任务执行完毕的时候,会读取消息队列中的异步任务,如果有可以执行的任务就把它放入执行栈中并开始执行。不断重复以上步骤,就是事件轮询。其中异步队列又存在宏任务和微任务的概念,微任务的优先级比宏任务高。

面试官:还可以,你提到了微任务比宏任务的优先级高,那你可以说说原因吗?或者说js为什么这么设计?

小白:(因为为了区分异步任务的优先级啊!为了让微任务的优先级比宏任务高啊!)咳咳,这么设计的原因主要是给异步任务一个“插队”的机会,防止后进入的任务永远在队尾的情况出现。

面试官:不错啊!我以往问别人,他们都说就是为了区分优先级。看来你确实理解了,不是简单的背八股。

小白:-。-!

面试官:既然你这么理解,请来做下这些输出题吧!

console.log(1)
setTimeout(() => {
  console.log(2)
})
new Promise((reslove) => {
  console.log(3)
  reslove()
}).then(() => {
  console.log(4)
})
console.log(5)

小白:1 3 5 4 2

面试官:这么快!那么下面这道呢?

console.log(1)
setTimeout(() => {
  console.log(2)
})
setTimeout(() => {
  console.log(3)
})
new Promise((reslove) => {
  console.log(4)
  reslove()
}).then(() => {
  console.log(5)
})
console.log(7)

小白:1 4 7 5 2 3

面试官:嫩快!你能说说你的思路吗?

小白:ok!我说一下第二题:首先设置俩队列,一个是任务队列,一个是消息队列。然后按照代码顺序从上对下捋,第一个log直接打印“1”,遇到了setTimeout函数,把里面的代码放到消息队列的宏任务队列中

const xiaoxiduilie = {
  microtask: [],
  macrotask: [console.log(2),],
}

接着又遇到一个setTimeout,也把其中的代码放到消息队列的宏任务队列中

const xiaoxiduilie = {
  microtask: [],
  macrotask: [console.log(2), console.log(3)],
}

接着遇到了一个promise对象,执行其中的同步代码,log一个“4”,把后续的代码放到微任务队列中

const xiaoxiduilie = {
  microtask: [console.log(5)],
  macrotask: [console.log(2), console.log(3)],
}

接着log一个“7”,至此同步代码执行完毕,任务队列为空,此时从消息队列按照先进先出,微任务优先的顺序,取任务执行。先看微任务队列有没有任务执行,log一个“5”。接着log宏任务队列“2 3”。所以最终结果是“1 4 7 5 2 3”。

面试官:不错不错,思路清晰,根本难不倒你,这个知识点就过了吧。