说事件循环(event loop)之前先要搞清楚几个问题。

1. js为什么是单线程的?
试想一下,如果js不是单线程的,同时有两个方法作用dom,一个删除,一个修改,那么这时候浏览器该听谁的?
2.js为什么需要异步?
如果js不是异步的话,由于js代码本身是自上而下执行的,那么如果上一行代码需要执行很久,下面的代码就会被阻塞,对用户来说,就是”卡死”,这样的话,会造成很差的用户体验。
3.js是如何实现异步的?
既然js是单线程的,那么js是如何实现异步的呢,是通过事件循环(event loop),理解了event loop 就理解了js的执行机制。
4.浏览器中的多线程?
js是单线程的,但是浏览器是多线程的,多个线程相互配合以保持同步,浏览器下的线程有
  • JavaScript引擎线程,用于解析JavaScript代码
  • GUI渲染线程,(它与javaScript线程是互斥的)
  • 事件线程(onclick,onchange,…)
  • 定时器线程(setTimeout, setInterval)
  • 异步http线程(ajax),负责数据请求
  • EventLoop轮询处理线程,事件被触发时该线程会把事件添加到待处理队列的队尾
说道浏览器的多线程,我们可以说一下,主线程和异步线程之间是怎么配合的:主线程发起一个异步请求(比如http请求),相应的工作线程接收请求并告知主线程已收到通知(异步函数返回);主线程可以继续执行后面的代码,同时工作线程执行异步任务;工作线程完成工作之后,通知主线程;主线程收到通知后,执行一定的动作(调用回调函数);
5. javaScript 的事件循环(event loop)
既然js是单线程的,那么所有的任务就需要排队执行。
  • javaScript 中的任务可以被划分为宏任务(Macrotask)或者微任务(Microtask)
  • 像鼠标事件,键盘事件,"ajax","setTimeout"等就属于宏任务,需要注意的是,主线程的整体代码(script标签),也是一个宏任务
  • process.nextTick,PromiseA.then(), MutaionObserver 就属于微任务
简单概括一下事件循环,就是
1.执行宏任务队列中第一个任务,执行完后移除它
2.执行所有的微任务,执行完后移除它们
3.执行下一轮宏任务(重复步骤2)
如此循环就形成了event loop,其中,每轮执行一个宏任务和所有的微任务
下图很形象的描述了event loop

网上有用异步任务和同步任务来说明这个问题的,但是我觉得用宏任务和微任务更好点。

下面我通过分析一个示例来说一下:
console.log(1);setTimeout(function(){console.log(2)
},10);new Promise(function(resolve){console.log(3)for( var i=100000 ; i>0 ; i-- ){i==1 && resolve()}console.log(4)
}).then(function(){console.log(5)
}).then(function(){ console.log(6) })console.log(7);

打印出来的结果是:1 3 4 7 5 6 2

我们分析一下整个过程

1. 首先执行主线程这个宏任务,从上到下执行,遇到console.log(1); 打印1出来

2. 遇到setTimeout,把它丢给定时器线程处理,然后继续往下执行,并不会阻塞10毫秒,而此处定时器线程会在,主线程执行完后的10毫秒,把回调函数放入宏任务队列。

3. 遇到new Promise,直接执行,先打印 ‘3‘ 出来,然后执行for循环,达到条件之后,把promise的状态改为resolved,继续执行打印 ‘4’ 出来

4.遇到promise的then, 属于微任务,则把回调函数放入微任务队列

5.又遇到promise的then, 属于微任务,则把回调函数放入微任务队列

6. 遇到console.log(7) 打印 ‘7’ 出来

7. 宏任务执行完后会执行所有待执行的微任务,所以会相继打印 ‘6’, ‘7’ 出来。

至此第一轮循环已经结束了,第一轮循环里的宏任务和微任务都会被移除出任务队列,接下来开启第二轮循环,

1.首先查找是否有宏任务,由于setTimeout 的回调被放入了宏任务队列,这里会执行回调函数的代码,打印了 ‘2’ 出来

2. 接着查找是否有微任务,发现没有微任务,则本轮循环结束

接下来会重复上面的步骤,这就是event loop 了。后续当我们触发点击事件,有回调函数的话,回调函数也会被放入宏任务队列,一旦队列里重新有了任务,就会被执行。

6. 扩展题目

如果能把上面这道题的流程说清楚,那么恭喜你,对event loop理解的不错了。 下面我们再利用上面的题目扩展一下,加深理解。

下面的代码打印出来的结果是什么?

console.log(1);setTimeout(function(){new Promise(function(resolve){console.log('promise in setTimeout1');resolve();}).then(function(){console.log('then in setTimeout1');})
},10);new Promise(function(resolve){console.log(3);for( var i=100000 ; i>0 ; i-- ){i==1 && resolve();}console.log(4)
}).then(function(){console.log(5);
});setTimeout(function(){console.log('setTimeout2');
},10);console.log(7);

结果如下:

可以发现,第二个setTimeout 的回调函数,执行的比第一个setTimeout里面的promise.then()的回调要晚,这是因为每次循环只执行一个宏任务,但是却会执行所有待执行的微任务,而第二个setTimeout在宏任务队列的位置在第一个setTimeout后面。

这个就是我理解的JavaScipt 事件循环机制,参考了很多文章,也自己做了很多思考写出来的,码字不易,觉得有帮助可以点个赞哦。也欢迎留言交流

参考文章

https://segmentfault.com/a/1190000012806637?utm_source=tag-newest

http://www.ruanyifeng.com/blog/2014/10/event-loop.html

https://zhuanlan.zhihu.com/p/33127885

https://zhuanlan.zhihu.com/p/33136054

https://stackoverflow.com/questions/25915634/difference-between-microtask-and-macrotask-within-an-event-loop-context

转载于:https://www.cnblogs.com/daisygogogo/p/10116694.html

JavaScipt 中的事件循环(event loop),以及微任务 和宏任务的概念相关推荐

  1. JavaScript基础:浅聊事件循环(Event LooP)以及微任务,宏任务,DOM渲染

    一直说JavaScript是单线程的执行的(当然也可以通过其它其它的方式异步,本篇暂时不聊). 内核的组成 首先聊一下浏览器的内核组成部分,当然下面也不是全部,而只是说一些常见的. 主线线程 js引擎 ...

  2. ajax是宏任务还是微任务,(滴滴面试)事件循环Event Loop及微任务和宏任务的执行过程详解...

    之前一直在面试,对于一些大厂面试题真的还是很注重原理和基础的, 还有就是数据结构和算法这种,校招的话,这些是很重要的, 前天和滴滴的人面试,问的真心觉得不难,而且也都是现在面试前端很常见的问题, 对于 ...

  3. php event loop,理解javascript中的事件循环(Event Loop)

    背景 在研究js的异步的实现方式的时候,发现了JavaScript 中的 macrotask 和 microtask 的概念.在查阅了一番资料之后,对其中的执行机制有所了解,下面整理出来,希望可以帮助 ...

  4. 技术干货 | JavaScript 之事件循环(Event Loop)

    导读:学过 JavaScript(下文简称 JS) 的都知道它是一门单线程的.非阻塞的脚本语言.单线程意味着,JS 代码在执行的任何时候,都只有一个主线程来处理所有的任务,这也就意味着 JS 无法进行 ...

  5. python事件循环_简单了解一下事件循环(Event Loop)

    关于我 一个有思想的程序猿,终身学习实践者,目前在一个创业团队任team lead,技术栈涉及Android.Python.Java和Go,这个也是我们团队的主要技术栈. Github:https:/ ...

  6. JavaScript 异步执行的学习笔记 - 什么是事件循环 Event loop?

    原文 使用像 JavaScript 这样的语言进行编程时,最重要但也经常被误解的部分之一是如何表达和操作一段需要某段时间才能完成执行的程序行为. 这不仅仅是从 for 循环开始到 for 循环结束发生 ...

  7. JAVA script 循环 图片_深入分析JavaScript 事件循环(Event Loop)

    事件循环(Event Loop),是每个JS开发者都会接触到的概念,但是刚接触时可能会存在各种疑惑. 众所周知,JS是单线程的,即同一时间只能运行一个任务.一般情况下这不会引发问题,但是如果我们有一个 ...

  8. 面试率 90% 的JS事件循环Event Loop,看这篇就够了!! !

    面试率 90% 的JS事件循环Event Loop,看这篇就够了!! ! 事件循环(Event Loop)大家应该并不陌生,它是前端极其重要的基础知识.在平时的讨论或者面试中也是一个非常高频的话题. ...

  9. javascript事件循环Event Loop,宏任务与微任务

    1.javascript的运行机制介绍 javascript是单线程的语言,默认情况下一个时间点只能做一件事情,因此引入异步模型javascript是一门解释性脚本语言,即(边解释边运行) 2.阻塞式 ...

最新文章

  1. 优雅地分离tableview回调
  2. %matplotlib inline的含义
  3. stm32之spi之NSS管脚信号
  4. 利用计算机或图形计算器在,图形计算器在函数教学中的应用
  5. 汇编语言-012(扩展加法指令ADC、带借位减法指令SBB、执行加法后进行ASCII调整指令、AAS 、AAM、AAD 、DAA指令将和数转成压缩十进制格式)
  6. anaconda中tensorflow-estimator版本应与tensorflow-gpu版本相同
  7. 热烈庆祝《Python可以这样学》在台湾发行繁体版
  8. 2021年福建高考成绩位次查询,2021年福建普通高考理科成绩一分一段表汇总(成绩排名查询)...
  9. 下一步怎么办?核心网带宽必须迅猛增长!
  10. 【Redis】Redis学习(四) Redis Sentinel模式详解
  11. 深入理解Python中赋值、深拷贝(deepcopy)、浅拷贝(copy)
  12. 跟小丸子学基础口语16-20
  13. 倾斜摄影在农房一体不动产测量中的技术流程(Smart3D+EPS)
  14. c++,kmin,kmax
  15. Jetson Tegra X系列刷机教程
  16. SecTalks: BNE0x00 - Minotaur靶机
  17. 移动端 php 开源,poscms移动端地址函数
  18. 超稳定的接口——淘宝/天猫获得淘宝商品详情
  19. JavaScript设计模式 Item 6 --单例模式Singleton
  20. idea输入英文时,间距变大报红 cannot resolve symbol ‘xxx‘

热门文章

  1. swift禁用webView对H5中数字,链接,日期,地址,电话号码做解析
  2. windows下使用Python来修改文件时间戳
  3. sharepoint 2010 内容类型
  4. oracle 强制 断开,ORA-01092 ORACLE 实例终止。强制断开连接 解决方案(下)
  5. android gridview 中图片大小不一,android – Gridview及其图像不适合所有屏幕大小
  6. mysql 中文 length_mysql length()中文长度一些问题整理
  7. 2003配置php环境,2003配置PHP环境(有利于升级)
  8. portainer忘记用户名密码_【20201122】做个用户管理系统(6)——忘记密码页面、重置密码方式页面的模板制作...
  9. js---PC端滑动进度条
  10. SpringBoot-14-MyBatis预热篇,MySQL小结