一,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事件循环机制-宏任务微任务相关推荐

  1. JS事件循环机制:同步与异步任务 之 宏任务 微任务

    JS事件循环机制:同步与异步任务 之 宏任务 微任务 阅读目录 javascript事件循环 setTimeout和setInterval中的执行时间 宏任务和微任务 javascript是单线程,一 ...

  2. js事件循环机制(await-async-事件循环)

    await和async 异步函数 async function async关键字用于声明一个异步函数: async是asynchronous单词的缩写,异步.非同步: sync是synchronous ...

  3. js事件循环机制和优先级

    浏览器的渲染进程是多线程,包括 GUI渲染线程 js引擎线程 事件触发线程 定时器触发线程 异步http请求线程 主执行栈和任务队列 所有的任务可以分为同步任务和异步任务,同步任务,顾名思义,就是立即 ...

  4. 彻底搞懂JS事件循环机制(event loop)

    知识点: js异步实现 EventLoop.消息队列 宏任务 与 微任务 同步模式与异步模式 首先要确定 js是单线程语言,js在设计之初用作用户互动,以及操作DOM.这决定了它只能是单线程(例如多线 ...

  5. js结束当前循环关键词_干货||什么是事件循环机制

    事件循环机制 经常有小伙伴问到我什么是 js 的事件循环机制,这里我就简单来给这些有困惑的小伙伴进行一下解答. 我将从下面几个方面来循序渐进的为大家来进行讲解: 区分进程和线程 浏览器的多进程 浏览器 ...

  6. Event loop/浏览器的事件循环机制

    一.Event loop引入 1.js为什么是单线程的? 之前我们已经学习了浏览器的关键渲染路径,知道了网页内容交给浏览器后浏览器是如何解析.渲染.绘制的,也提到了浏览器是多线程的,js是单线程的,那 ...

  7. js事件循环——看输出顺序

    js事件循环: 由于js是单线程的,同一时间只能干一件事情,当期宿主环境为浏览器时,若一个任务耗时过长会导致页面阻塞.因此有了js事件循环机制,它将任务分成同步任务和异步任务,同步任务在主线程不断执行 ...

  8. 对JavaScript事件循环机制的理解

    前言: 这次主要整理一下自己对 Js事件循环机制,同步,异步任务,宏任务,微任务的理解,大概率暂时还有些偏差或者错误.如果有,十分欢迎各位纠正我的错误! 一.事件循环和任务队列产生的原因: 首先,JS ...

  9. JavaScript事件循环机制

    众所周知JS是一门单线程执行环境的语言,对于同步任务而言,同一时刻只能执行一个任务,后续的任务都要在当前执行的任务后面排队.这种模式在遇到一些执行时间较长的任务的时候就会出问题,会导致页面失去响应.所 ...

  10. js的事件循环机制:同步与异步任务(setTimeout,setInterval)宏任务,微任务(Promise,process.nextTick)...

    javascript是单线程,一切javascript版的"多线程"都是用单线程模拟出来的,通过事件循环(event loop)实现的异步. javascript事件循环 事件循环 ...

最新文章

  1. 适配器模式(三种)简单使用
  2. 弱电工程光纤传输基础知识
  3. Database之SQLSever:SQL命令实现理解索引、规则、默认概念及其相关案例之详细攻略
  4. 网页UTF8编码--多出空白行的问题(ZT)
  5. 判断jQuery选择器结果为空 - CSDN博客
  6. Kafka(六)Kafka基本客户端命令操作
  7. java主要用来开发什么_java主要用来开发什么软件
  8. 微软最强命令行工具发布,强势霸榜GitHub
  9. java 保存微信表情_【java】【mysql】存储微信表情emoji表情
  10. 硬件中控一键开关机设计方案
  11. 计算机软件系统的三个层次,计算机软硬件系统
  12. 毕达哥拉斯定理/勾股定理
  13. 致青春触动心灵的英语美文——小寓言大智慧
  14. SSM项目-我爱我家(二)
  15. 微信小程序与HTML5的标签差异梳理
  16. ngrok转发mysql连接_ngrok内网转发
  17. 等差数列java_java简单的编程(等差数列)
  18. 我的涨分日记(二)——BestCoder Round #59
  19. 如何在苹果笔记本上装win7系统
  20. mac OSX上eclipse adb无法识别(调试)小米的解决方案

热门文章

  1. Linux进程优先级取值范围,Linux中使用nice和renice命令:改变进程优先级
  2. 【AMAD】django-compressor -- 将JS和CSS文件压缩为一个缓存文件
  3. 设计者模式详解--状态模式
  4. elasticsearch6.1.3 集成分词器
  5. 对于PHP面试知识点的小结
  6. Apache VirtualHost的配置
  7. C#保存图片到数据库,读取图片显示
  8. realmex7pro能用鸿蒙系统吗,realmex7pro有nfc吗-realmex7pro支持红外遥控功能吗
  9. 浅谈Http协议、TCP协议
  10. redis info信息注解