参考文章:深入理解JS引擎的执行机制        JavaScript 异步、栈、事件循环、任务队列

我的笔记:ES系列之Promise async 和 await

Event Loop

前提

  • js是单线程的

  • js的Event Loop是JS的执行机制,深入了解JS的执行,就等于深入了解JS里的event loop。

问:js是为单线程的,为什么要实现异步,单线程怎么实现异步?

答:1、js的单线程能够保证对DOM操作的顺序性,如果是多线程,A线程编辑DOM上的内容,B线程删除该DOM,那么,浏览器该怎么执行了。

2、因为js是自上而下执行的,如果上一行解析很长时间,下面的代码解析不了,造成页面卡死。

3、通过事件循环机制实现异步

js的Event Loop1

demo1

console.log(1)

setTimeout(function () {
console.log(2)
}, 0) console.log(3)

执行结果:1 3 2

首先我们知道,js将任务分为同步任务异步任务

js的执行机制:

判断当前执行代码是同步还是异步的,同步就进入主线程执行,异步就放到event table

然后异步任务在event loop中注册函数,当满足条件后,就被推进event queue

同步任务进入主线程一直执行,知道主线程空闲时,才会去event queue中查看是否有客执行的异步任务,如果有就推入主线程中。

js的Event Loop2

<script>
console.log('1');
setTimeout(function(){
console.log('2')
}); new Promise(function(resolve){
console.log('3');
for(var i = 0; i < 10000; i++){
i == 99 && resolve();
}
}).then(function(){
console.log('4')
}); console.log('5');
</script>

按照上面的分析,执行顺序为:1 5 2 3 4;但是实际的执行顺序为:1 3 5 4 2

这是为什么呢?

这是因为,js将任务分为宏任务(macro-task)微任务(micro-task)

宏任务包括:script标签、setTimeout、setInterval

微任务包括:Promise,process.nextTick

  1. 执行到script标签进入宏任务,然后执行

  2. setTimeout为宏任务,放在任务队列中,等待该宏任务以及该宏任务中的微任务执行完毕后执行

  3. Promise准备开启微任务,但是没有开启,.then()进入微任务,等待该宏任务执行完毕后执行该微任务

setTimeout

 setTimeout(function(){
console.log('执行了')
},3000)

我们一般说以上代码会在3s后执行,但是准确的解释是: 3秒后,setTimeout里的函数被会推入event queue,而event queue(事件队列)里的任务,只有在主线程空闲时才会执行。

如果主线程执行了5s,那么以上代码会在5s,以及事件队列的前面的微任务执行完毕后执行。

JS高级学习笔记(6)- 事件循环的更多相关文章

  1. 转:JS高级学习笔记(8)- JavaScript执行上下文和执行栈

    必看参考: 请移步:博客园 JavaScript的执行上下文 深入理解JavaScript执行上下文和执行栈 JavaScript 深入之执行上下文 写在开头 入坑前端已经 13 个月了,不能再称自己 ...

  2. JS高级学习笔记(9) 之 转:前端路由跳转基本原理

    原文链接: 前端路由跳转基本原理 前述 前端三大框架Angular.React和Vue都推行单页面应用SPA开发模式,这是因为在路由切换时,替换DOM Tree中发生修改的DOM部分,来减少原来因为多 ...

  3. JS高级学习笔记(1)- 数据类型及转换规则

    必读: Javascript对象Oject的强制类型转换 JavaScript筑基篇(二)->JavaScript数据类型 聊一聊valueOf和toString 深入理解JavaScript系 ...

  4. JS高级学习笔记(10) 之 js 时怎么解析HTML标签的

    DOM 节点类型 浏览器渲染过程 浏览器是怎么把HTML标签语言和JavaScript联系在一起的,这就是我们常说的DOM. 浏览器中的DOM解析器把HTML翻译成对象(object),然后JavaS ...

  5. JS高级学习笔记(2)之js多线程

    参考大神:Javascript多线程 web worker ---- 6.Web Worker 概述 截图过来: 线程之间的通信 let worker = new Worker(‘js文件路径’) 主 ...

  6. js高级程序设计笔记之-addEventListener()与removeEventListener(),事件解除与绑定

    js高级程序设计笔记之-addEventListener()与removeEventListener(),事件解除与绑定 addEventListener()与removeEventListener( ...

  7. js再学习笔记

    #js再学习笔记 ##基本 1.js严格区分大小写   2.js末尾的分号可加,也可不加   3.六种数据类型(使用typeof来检验数据的类型) `typeof` - undefined: `var ...

  8. Python高级学习笔记

    Python高级学习笔记,此笔记中包含Linux操作系统.Html+CSS+JS.网络协议等. 所有思维导图为本人亲手所画,请勿用于商用. 大哥们,求点赞哦. 第一天笔记:链接 第二天笔记:链接 第三 ...

  9. JS数组学习笔记

    原文:JS数组学习笔记 最近在备课数组,发现很多ES5的方法平时很少用到.细节比较多,自己做了大量例子和整理,希望对大家了解JavaScript中的Array有所帮助. 概念 数组是值的有序集合.每个 ...

随机推荐

  1. c基本语法介绍

    c语言基本语法介绍 1.把常量定义为大写字母形式,是一个很好的编程实践.

  2. HTML5学习第四天

    HTML5学习第四天 一.HTML列表 HTML列表,有无序表,有序表以及自定义表,列表于列表之间可以实现嵌套 列表相关操作 <ul> <li>(多选)谁世界第二可爱?< ...

  3. MySQL学习之SQL基础(一)DML

    DML(data Manipulation language) INSERT DELETE UPDATE SELECT INSERT mysql> desc emp; +----------+- ...

  4. blog编辑技巧

    blog里添加目录 添加版权声明 其他 更新日志: 20190719, 添加目录,增加章节:[添加版权声明] blog里添加目录 https://szosoft.blogspot.com/需要使用绝对 ...

  5. SpringBoo#Mybatis多个数据源配置,Sqlite&Mysql

    第一步:排除数据源的自动配置类: @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) 第二步:定义好两个数据源的 ...

  6. 使用JavaScript实现一个简单的编译器

    在前端开发中也会或多或少接触到一些与编译相关的内容,常见的有 将ES6.7代码编译成ES5的代码 将SCSS.LESS代码转换成浏览器支持的CSS代码 通过uglifyjs.uglifycss等工具压 ...

  7. 042、Java中逻辑运算之短路或运算“||”

    01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...

  8. C++用sqlite3_open连接打开指定数据库的小问题

    一开始我也纳闷,我以为是我数据库没弄好,但是当我仔细检查,才发现 原来我少了分号 写少了分号,可能会导致  database    和  table    找不到... 所以用的时候需要注意... 代 ...

  9. Centos7忘记mysql的root用户密码

    1.先停止mysql服务 ​[root@CentOS ~]# ps -ef | grep mysql root : pts/ :: /bin/sh /usr/local/mysql/bin/mysql ...

  10. ROM与RAM

    今天小姐姐来问我关于ROM.RAM和Flash的区别,我给她大致的说了一下名称和作用.可人家说她知道这玩意的名字,希望我能够接地气的解释一下什么是ROM.RAM.FLASH…… 这就把我难住了 ≧ ﹏ ...