前言
javascript是单线程的语言,也就是说,同一个时间只能做一件事。而这个单线程的特性,与它的用途有关,作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准?
为了利用多核CPU的计算能力,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程,但是子线程完全受主线程控制,且不得操作DOM。所以,这个新标准并没有改变JavaScript单线程的本质
这是今天一个朋友发给我的一个面试题,
感觉还挺有意思的,
写个博客以供分享
先看看这个面试题目:
观察下面的代码,写出输出结果
console.log('0') setTimeout(function () { console.log('1'); }); new Promise(function(resolve,reject){ console.log('2') resolve(3) }).then(function(val){ console.log(val) }) console.log(4)
输出结果: “0” “2” 4 3 “1”
今天主要是分析为什么输出结果是这样的?这就和 javascript 的执行机制密切相关了.
Event Queue 和 Event Loop
javascript 是一门单线程的语言, 这就意味着在执行代码的时候, 都只有一个主线程来处理所有的任务.
我们都知道 javascript 包括同步代码和异步代码, 那么 javascript 是怎么处理这两种情况的呢?
这里我们引进了 Event Queue 事件队列这一概念. 所有异步操作的回调都会进入到这里. 然后等到主线程空闲, 就会从这里调取回调执行.
setTimeout
setTimeout 相信大家都有使用过, 可以延时执行并且是异步执行的.
但是有时候我们得到的结果往往是代码实际执行的时间比我们想要延时执行的时间要久。这又是为什么呢?
这就和我们之前所说的 Event Loop 有关了, 我们可以来具体看下 setTimeout 的执行步骤:
setTimeout(function () { asyncFn() }, 1000); syncFn()
所以有时候会出现代码实际执行时间比延时时间长的情况。
宏任务和微任务
之前我们说过异步任务会进入到事件队列中, 不同类型的任务会进入到不同的队列中, 比如宏任务会进入到宏任务队列中, 微任务会进入到微任务队列中.
我们只要记住 当当前执行栈执行完毕时会立刻先处理所有微任务队列中的事件,然后再去宏任务队列中取出一个事件。同一次事件循环中,微任务永远在宏任务之前执行
这时候我们就可以解释一开始的代码执行结果了:
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对菜鸟教程(cainiaojc.com)的支持。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:notice#cainiaojc.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。