当前位置:网站首页 > Vue.js开发 > 正文

js事件循环机制-宏任务微任务

一,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/OUI 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中代码,实行先进先出,所以依次打印36 微任务Event Queue中代码执行完,就执行宏任务Event Queue中代码,也是先进先出,依次打印17。 最终结果:24510893617 
到此这篇js事件循环机制-宏任务微任务的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!

版权声明


相关文章:

  • 对修饰器的实验支持功能在将来的版本中可能更改。在 “tsconfig“ 或 “jsconfig“ 中设置 “experimentalDecorators“ 选项以删除此警告。ts(1219)2024-11-29 23:54:09
  • vue-cli2.0webpack的理解2024-11-29 23:54:09
  • vue3初探-工程化项目架构-笔记2024-11-29 23:54:09
  • vue3代码的组织形式2024-11-29 23:54:09
  • js基础-(二)-类和面向对象2024-11-29 23:54:09
  • vue安装npm时遇到 npm ERR! syscall rename npm ERR!错误解决办法2024-11-29 23:54:09
  • vue post application/x-www-form-urlencoded传参的解决方案2024-11-29 23:54:09
  • 移动端兼容安卓456实现0.5像素边框2024-11-29 23:54:09
  • VUE实现吸底2024-11-29 23:54:09
  • VUE页面不刷新时调用forceUpdate即可2024-11-29 23:54:09
  • 全屏图片