Hello,大家好,我是 Sunday。
【看代码说结果】一直是前端面试中的常见问题。最近在陪几个同学面试过程中,几乎每个中、大厂的面试都会遇到一个或几个这样的问题。
虽然这样的问题如此高频,但是能够回答好的同学却寥寥无几。
每次事后跟同学沟通,得到的结果都是:“实际开发中没有这么写的,NND 奇葩面试题!” 大家是不是也会有相同的感受呢?
是的!实际开发中我们肯定不会写出面试题里的凌乱场景。但是,我们不要忘记,学习的目的是:为了拿到更高薪资的 offer!,所以对很多同学而言 面试 比 实际开发 更重要! 只有很好的解决了 面试 的问题,大家才可以拿到满意的 offer。
所以,解决【看代码说结果】的问题就变得至关重要了。那么咱们今天,就好好地来聊聊 JS 中的执行机制问题,帮大家彻底理解 JS 的执行逻辑!
JavaScript 是一种单线程语言。
虽然最新的 HTML5 中引入了 Web Worker,但 JavaScript 单线程的核心保持不变。
因此,JavaScript中所有的“多线程”都是用单线程模拟的,JavaScript中的所有多线程都是骗人的!
由于 JavaScript 是单线程的,它就像一家只有一个窗口的银行,客户需要一一排队来处理交易。
同样,JavaScript 任务也需要按顺序执行,一个接一个。如果一项任务花费太长时间,则下一项任务必须等待。
那么问题就来了:如果我们想浏览新闻,但新闻中的高清图片加载缓慢,我们的网页是否要一直卡住,直到图片完全显示出来?
因此,JS将任务分为两类:
当我们打开一个网站时,网页的渲染过程由一堆同步任务组成,例如:骨架屏幕、页面元素。
消耗大量资源且需要很长时间才能完成的任务(例如:加载图像、音乐文件)则是异步的。
图片
那么 JS 是如何知道主线程为空的呢?
在 JavaScript 引擎有一个监控进程,不断检查主线程执行栈是否为空。一旦为空,它就会去事件队列检查是否有任何函数正在等待调用。
如下面的代码所示:
let data = [];$.ajax({ url:www.lgdsunday.club, data:data, success:() => { console.log('发送成功!'); }})console.log('代码执行完成');
上面是一个简单的ajax请求代码:
通过上面的文字和代码,大家应该对JavaScript中的执行顺序有了初步的了解了吧。
那么接下来咱们来看一个 扰乱执行顺序的 “元凶” setTimeout。
setTimeout 可以延迟执行代码,比如:
setTimeout(() => { task();},3000)console.log('一个普通的打印');
根据我们之前的结论,setTimeout是异步的。所以,同步任务console.log应该先执行。因此,我们的结论是:
// 一个普通的打印// task()
但是,这里我们要注意 3000 毫秒并不是 task 的执行时间,而是 task 进入任务队列(主线程)的时间
那么同样的道理,在面试中常见的 setTimeout(fn, 0) 的延迟 0 毫秒 是什么意思呢?
setTimeout(fn ,0)是指定当堆栈中的所有同步任务完成且堆栈变空时,应在主线程上最早可用的空闲时间执行某个任务,而不需要等待任何额外的秒数。
所以,setTimeout(fn, 0) 并不会立刻执行。
宏任务与微任务的概念在这种题目中也是必须要掌握的。
事件循环中事件的顺序决定了JavaScript代码的执行顺序。
我们通过一段代码来看下这个问题:
setTimeout(function() { console.log('setTimeout');})new Promise(function(resolve) { console.log('promise');}).then(function() { console.log('then');})console.log('console');
本文链接://www.dmpip.com//www.dmpip.com/showinfo-26-89413-0.html这一次,彻底解决面试中看代码说结果的问题!
声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com