一,js是基于V8引擎的单线程运行机制:也就是在主线程中,代码的执行是顺序执行的
但是如果遇到了一些异步操作如:
宏任务:setTimeout、setInterval, Ajax,DOM事件 微任务:Promise async/await
它们的执行需要一定的时间,如果还是单单使用主线程,就会因为这些耗时长的操作而堵住,程序无法接着执行,这就是平时所说的阻塞。
为了达到非阻塞的目的,就有了异步非阻塞的概念,在js中,异步操作的处理都是异步非阻塞。
举一个简单的例子:
烧开水: 你有一堆事abc情要做,还要烧一壶开水,但是烧开水需要一定的时间,为了把等待的这个时间利用起来,而不是你守在热水壶旁边啥也干不了等水烧开。(同步阻塞) 人们在热水壶上安装一个哨子,当水烧开就会发出声音,提醒你水烧开了。这烧水的期间,你就可以去做其他事情,只要听到哨声,把电关了就行。(异步非阻塞)
二,同步操作和异步操作的处理
这张图是其他博客上复制来的哈,已经很明确地表现出同步操作和异步操作地处理方式了。
也就是说,主线程中的所有代码依次顺序执行,遇到同步则直接执行,遇到异步,则在Event Table中注册异步(类比于烧水事件中的把水壶的电插上)。这些操作无需花费多少时间的。
等到异步操作的结果出来了,就把回调函数注册到事件队列中去(类比于水壶的哨声响了,需要人去关电这一事件)。
另外js的事件执行有一个轮询的机制:等到主线程空了,就去事件队列中查找要执行的事情放入主线程,然后同步的执行,异步的注册,而注册的异步结果出来了放入事件队列中。主线程空了再去,空了再去……(这就是Event Loop事件循环)
所以说下面这个例子:
<script type="text/javascript"> setTimeout(function(){
console.log('定时器第一个') },100); setTimeout(function(){
console.log('定时器第二个') },0); console.log('代码执行结束') </script>
返回的结果就会是:
三,异步操作又区分为宏任务和微任务
宏任务
包括 整体代码script,setTimeout,setInterval ,setImmediate,I/O,UI renderingnew ,Promise* DOM渲染后触发
微任务
包括 Promises.(then catch finally),process.nextTick, MutationObserver DOM渲染前触发
区别
宏任务和微任务的区别在于在事件循环机制中,执行的机制不同 每次执行完所有的同步任务后,会在任务队列中取出异步任务,先将所有微任务执行完成后,才会执行宏任务 所以可以得出结论, 微任务会在宏任务之前执行。 我们在工作常用到的宏任务是 setTimeout,而微任务是 Promise.then 注意这里是Promise.then,也就是说 new Promise在实例化的过程中所执行的代码是同步的,而在 then中注册的回调函数才是异步。
setTimeout(function(){
console.log('1') }); new Promise(function(resolve){
console.log('2'); resolve(); }).then(function(){
console.log('3') }); console.log('4'); new Promise(function(resolve){
console.log('5'); resolve(); }).then(function(){
console.log('6') }); setTimeout(function(){
console.log('7') }); function bar(){
console.log('8') foo() } function foo(){
console.log('9') } console.log('10') bar()
解析:
首先浏览器执行Js代码由上至下顺序,遇到setTimeout,把setTimeout分发到宏任务Event Queue中 new Promise属于主线程任务直接执行打印2 Promis下的then方法属于微任务,把then分到微任务 Event Queue中 console.log(‘4’)属于主线程任务,直接执行打印4 又遇到new Promise也是直接执行打印5,Promise 下到then分发到微任务Event Queue中 又遇到setTimouse也是直接分发到宏任务Event Queue中,等待执行 console.log(‘10’)属于主线程任务直接执行 遇到bar()函数调用,执行构造函数内到代码,打印8,在bar函数中调用foo函数,执行foo函数到中代码,打印9 主线程中任务执行完后,就要执行分发到微任务Event Queue中代码,实行先进先出,所以依次打印3,6 微任务Event Queue中代码执行完,就执行宏任务Event Queue中代码,也是先进先出,依次打印1,7。 最终结果:2,4,5,10,8,9,3,6,1,7
到此这篇js事件循环机制-宏任务微任务的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!
版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/qdvuejs/11092.html