[面试官]再问javascript事件循环要如何应对?

大家好,我是梦兽编程。

梦兽编程是非常讨厌八股文。但是出于无奈也没办法,市场就是这样。技术探讨本来是经验的分享,而在我国的情况变成了9年义务教育的死板"教科书"。

很多时候我们会被资本家压榨到无法思考,还那有空了解那些面试题的实际知识点?如果你刷到本片文章,那么所有的面试题背后的知识点将有梦兽编归纳总结放到那些被问烂的前端面试题栏目中进行更新迭代。从问题的出现与考点进行解答。

期待你的收藏我的个人网站。

加入梦兽编程微信群juejin.cn/user/206673...

javascript 事件循环?

相信大家会经常被一道关于事件循环的面试题被恶心到,这到题目你能找到诀窍就很容易解决。如果不理解那就会一直被恶心到的面试题。

要理解这道题其他也很简单,首先你要知道javascript是单线程的运行机制,在一些比较耗时的操作中js会把他调到别的地方进行计算等到计算出结果后在回来执行,避免我们的ui线程操作的过程出现卡顿的问题。

其实并没有多大的问题,只是我们在开发过程中遇到比较耗时的任务可以想到用使用异步来解决就好了,但是就是有那么一批人喜欢那这种机制来考察你是不是很"努力"。

如果你不是要写类似React fiber算法,开发过程中编写应用层逻辑代码比较多情况下,了解这个对你帮助几乎为零。

但是我们国家就是有那么一些企业喜欢问,也挺无奈。

毕竟人生苦短及时行乐,除非你是想当科学家。

事件队列

因为javascript是单线程,所以我们的所有执行都可以不可能并行执行,为了让程序可以高速的运作。我们往往会把我们的操作放入一个队列中进行消费,包括高并发的web服务器中也有这么一个组件叫做"消息队列"。

我们可以把尽可能多大处理放在一个队列中,让队列给我们有序的执行来保证系统的执行顺序。在web服务器开发中有一个指标叫做吞吐量。有了队列我们就可以让提高了吞的能力,那么吐的能力就看你如何消费这些存在队列中的事件了。

事件循环

由于javascript是单线程,javascript又把比较耗时的任务给了你能够在后台计算的能力。单线程执行的过程中为了保证有序我们上面知道有一个队列的概念,但是javascript里面有两个队列,一个叫做同步队列也叫做宏队列,一个叫做异步队列也叫做异步队列。

问题来了这两个队列分别单独执行时它的有效性我们都能理解,但是两个合并在一起那就有问题了。所以javascript给出了一个解决方法。

同步任务执行找到所有异步任务,把这些异步任务全部放到异步任务队列中,等待同步任务执行完后,去执行异步队列中的任务。

异步队列中继续找到所有的同步任务和异步任务。在把同步任务执行完后去执行异步队列中的任务,以这样的同步与异步的交替执行,直到把所有的队列事件执行完后程序执行结束。

真题分析

scss 复制代码
setImmediate(() => {
  console.log(1)
}, 0)
setTimeout(() => {
  console.log(2)
}, 0)
new Promise((resolve) => {
  console.log(3)
  resolve()
  console.log(4)
}).then(() => {
  console.log(5)
})
async function test() {
  const a = await 9
  console.log(a)
  const b = await new Promise((resolve) => {
    resolve(10)
  })
  console.log(b)
}
test()
console.log(6)
process.nextTick(() => {
  console.log(7)
})
console.log(8)

在这道题我们按照上面的理解,先找出所有的同步任务。通过第一轮的分析我们得到下面的结论

首先settimeout属于同步任务中的延迟执行,所以在队列中先占了一个坑位。我先不要管。按照同步队列的执行顺序找到异步队列中的执行顺序一个一个往异步队列中进行添加。得到上面的关系图。

所以我们很容易得到

3 -> 4 -> 6 -> 8 -> 7 -> 5 的顺序,我们看到

这个时候我们就可以去执行异步队列里面的东西了。

我们这里需要注意的是test里面使用了await可以理解成强制把异步变成同步的意思。 所以我们也得到了

9->10->7 的结果

最后我们把上面延迟执行的两个同步任务不上,那么我们就可以得到以下结果

3 -> 4 -> 6 -> 8 -> 7 -> 5 -> 9 -> 10 -> 7 -> 1 -> 2。

再来一道简单的

javascript 复制代码
console.log(1)
setTimeout(function(){
	console.log(2)
},1000)
new Promise(function(resolve,rejected){
console.log(3)
	resolve('同步任务结果')
}).then(res=>{
	console.log('4',res)
})
console.log(5)

同样的操作方式

file

所以我们很容易就得到第一次的同步任务结果1 -> 3 -> 5和执行异步任务队列->4后再执行延迟任务->2

最后我们得到的结果就是 1 -> 3 -> 5 -> 4 -> 2

面试遇到半桶水的面试官怎么办?

比如第一道题目中这个题目出自github.com/OBKoro1/web....

但是它给的答案和解释都是错误的,完全是没有自己再浏览器中执行跑一遍就拿出来分享自己的经验了。这个时候如果你按梦兽编程的给的方式解答出来了,但是面试官明显再说你的答案是错的时候。你该怎么办?

这个时候你不要灰心,那就直接换个话题或者引导面试官问下一个大众都熟悉的问题。

面试的过程中不会因为你打错一个问题而否认你,最多会扣点分,千万不要和人辩论,原理愚昧最好的办法就是远离。

换个角度应聘是双向的,你都遇到这种半桶水的面试官了,你感觉这家公司的技术水平能好到哪里?

关于 JavaScript 事件循环,你这篇文章讲得非常详细,对我理解事件循环的机制有很大的帮助。

尤其是你对 setImmediate()、setTimeout()、Promise 和 async/await 的分析,非常清晰明了。

以下是一些我个人的想法:

  • 在面试前,可以先了解一下面试官的背景和经验。这样,在面试过程中,就可以根据面试官的水平来调整自己的回答。
  • 如果在面试中遇到自己不确定的问题,可以先承认自己不确定,然后再回去一定要去理解为什么是这样。

希望这些建议对你有所帮助。

本文使用 markdown.com.cn 排版

相关推荐
开开心心就好30 分钟前
高效报价软件,简化商铺定价流程
服务器·数据库·安全·面试·职场和发展·电脑·symfony
Mr_Mao3 小时前
Naive Ultra:中后台 Naive UI 增强组件库
前端
前端小趴菜055 小时前
React-React.memo-props比较机制
前端·javascript·react.js
摸鱼仙人~6 小时前
styled-components:现代React样式解决方案
前端·react.js·前端框架
sasaraku.7 小时前
serviceWorker缓存资源
前端
RadiumAg8 小时前
记一道有趣的面试题
前端·javascript
yangzhi_emo8 小时前
ES6笔记2
开发语言·前端·javascript
yanlele8 小时前
我用爬虫抓取了 25 年 5 月掘金热门面试文章
前端·javascript·面试
中微子9 小时前
React状态管理最佳实践
前端
烛阴9 小时前
void 0 的奥秘:解锁 JavaScript 中 undefined 的正确打开方式
前端·javascript