1. JS 是单线程

  • JavaScript 语言的一大特点就是单线程,也就是说,同一个时间只能做一件事
  • 这是因为 Javascript 这门脚本语言诞生的使命所致——JavaScript 是为处理页面中用户的交互,以及操作 DOM 而诞生的。
  • 比如我们对某个 DOM 元素进行添加和删除操作,不能同时进行。 应该先进行添加,之后再删除。
 单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就不得不一直等着。这样所导致的问题是: 如果 JS 执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。

问题

以下代码执行的结果是什么?

 console.log(1);   // 先打印1setTimeout(function () {console.log(3); // 1s钟之后打印3}, 1000);console.log(2);
// 如果是单线程,这个代码只有在打印3之后,才打印2。 时间比较久,需要等待上个定时器执行完成
// 如果是多线程,就会打印1,直接打印2,再去打印3 (实际打印:1,2,3)

那么单线程,多线程是什么呢?继续往下走:

2. 同步任务和异步任务

​ 单线程导致的问题就是后面的任务等待前面任务完成,如果前面任务很耗时(比如读取网络数据),后面任务不得不一直等待!!

​ 为了解决这个问题,利用多核 CPU 的计算能力,HTML5 提出 Web Worker 标准,允许 JavaScript 脚本创建多个线程,但是子线程完全受主线程控制。于是,JS 中出现了同步任务异步任务

同步

​ 前一个任务结束后再执行后一个任务,程序的执行顺序与任务的排列顺序是一致的、同步的。比如做饭的同步做法:我们要烧水煮饭,等水开了(10分钟之后),再去切菜,炒菜。

异步

​ 你在做一件事情时,因为这件事情会花费很长时间,在做这件事的同时,你还可以去处理其他事情。比如做饭的异步做法,我们在烧水的同时,利用这10分钟,去切菜,炒菜。

JS中所有任务可以分成两种,一种是同步任务(synchronous),另一种是异步任务(asynchronous)。同步任务指的是:在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;
异步任务指的是:不进入主线程、而进入”任务队列”的任务,当主线程中的任务运行完了,才会从”任务队列”取出异步任务放入主线程执行。

理解

同步,不是两件事情同时去做,而是先做一件事情,然后再做另一件事情。他是单线程,一个人依次做多件事情

异步,是两件事情同时去做,他是多线程,多个人同时做多个事情

同步任务,异步任务

再来看一个问题

console.log(1);setTimeout(function() {console.log(3);}, 0);
console.log(2);
// 结果还是1,2,3
// 为啥呢?继续往下走:

我们来看一下同步任务和异步任务:

了解完这一块之后,我们知道了刚刚的问题代码中,setTimeout的回调函数,是异步任务,放到任务队列了,但是为啥后执行呢?继续往下走:

3. JS执行机制

3.1 执行顺序

  1. 先执行执行栈中的同步任务。
  2. 异步任务(回调函数)放入任务队列中。(但是不执行回调函数
  3. 一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行。

如图:

3.2 事件循环

问题

console.log(1);
document.onclick = function () {console.log('click');
}
console.log(2);
setTimeout(function () {console.log(3)
}, 3000)

分析过程:

  1. 此代码中有两个异步任务,我们先给同步代码和异步代码分开:

  2. 当主线代码执行完了之后,1,2打印完了。

  3. 3s之后,定时任务时间到了,就将fn放到异步任务的任务队列中了:

  4. 然后执行异步任务的打印3。最终出现1,2,3。

  5. 如果setTimeout的回调函数的任务执行完成,异步任务队列就为空了。

  6. 如果此时点击了document,onclick的回调函数就放到异步任务了

  7. 然后执行,最终出现1,2,3,click

  8. 执行完了,异步任务又会清空

  9. 最后有个注意事项,主线程代码执行完成之后,会反复去异步任务中看是否有任务需要执行

    由于主线程不断的重复获得任务、执行任务、再获取任务、再执行,所以这种机制被称为事件循环( event loop)

事件循环综合图:

3.3 代码思考题

 console.log(1);document.onclick = function() {console.log('click');}setTimeout(function() {console.log(3)}, 3000)console.log(2);

4.宏观任务和微观任务

4.1 宏观任务:

宿主发起的任务为宏观任务,如script(整体代码)、setTimeout、setInterval、setImmediate、I/O、ajax、UI交互事件、postMessage、MessageChannel

4.2 微观任务:

JavaScript引擎发起的任务为微观任务,如Promise.then、MutationObserver、process.nextTick(Node.js 环境)的意思就是定义出一个动作,并且让这个动作在下一个事件轮询的时间点上执行

如何分析异步执行的顺序

  • 首先我们分析有多少个宏任务;

  • 在每个宏任务中,分析有多少个微任务;

  • 根据调用次序,确定宏任务中的微任务执行次序;

  • 根据宏任务的触发规则和调用次序,确定宏任务的执行次序;

  • 确定整个顺序;

如下代码解析:

<script type="text/javascript">
console.log('1');setTimeout(function() {console.log('2');process.nextTick(function() {console.log('3');})new Promise(function(resolve) {console.log('4');resolve();}).then(function() {console.log('5')})
})
process.nextTick(function() {console.log('6');
})
new Promise(function(resolve) {console.log('7');resolve();
}).then(function() {console.log('8')
})setTimeout(function() {console.log('9');process.nextTick(function() {console.log('10');})new Promise(function(resolve) {console.log('11');resolve();}).then(function() {console.log('12')})
})`
</script>

第一个宏观任务:

  1. 第一个宏观任务script 作为整体进入主线程 遇到console.log(‘1’) 输出1
  2. 遇到setTimeout,宏观任务(现在第一个宏观任务script还没有执行完毕 会分配到宏观任务中 暂时还不会执行)
  3. 遇到下面的process.nextTick 分配到微观任务中
  4. 遇到Promise,new Promise直接执行,输出7。then被分发到微任务Event Queue中 5.此时的微观任务表中:process.nextTick,Promise.then 则执行结果为 6 8
    第一个宏观任务 执行结果 : 1 7 6 8

第二个宏观任务:

  1. 第二个宏观任务是第一个setTimeout
  2. 跟script的执行顺序是一样的 碰到console.log(‘2’) 执行2 process.nextTick会分配到微观任务 Promise会立即执行 然后.then分配到微观任务
    输出结果:2 4 3 5

第三个宏观任务:

第三个宏观任务就是第二个setTimeout 和第二个宏观任务执行顺序一样
输出结果 9 11 10 12

JS执行机制、同步和异步、宏观任务和微观任务相关推荐

  1. Js执行机制——同步和异步

    JS是单线程 JavaScript 语言的一大特点就是单线程,同一个时间只能做一件事.JavaScript 是为处理页面中用户的交互,以及操作DOM 而诞生的,比如我们对某个DOM元素进行添加和删除操 ...

  2. 【JavaScript】JS执行机制--同步与异步

    目录 单线程 同步与异步 事件循环 单线程 JavaScript语言具有单线程的特点,同一个时间只能做一件事情.这是因为JavaScript脚本语言是为了处理页面中用户的交互,以及操作DOM而诞生的. ...

  3. 【JavaScript】JS执行机制微任务和宏任务

    文章目录 一.了解JS执行机制 二. 异步任务(宏任务.微任务) 1.宏任务 2.微任务 三.实操演练 解析: 一.了解JS执行机制 在学习 promise(期约) 之前,我们需要了解JS的执行机制, ...

  4. 同步异步、JS执行机制、事件循环

    文章目录 单线程 同步 异步 同步任务 异步任务 JS执行机制 异步进程处理 事件循环-event loop(这里主要是说浏览器事件循环) 单线程 JS的一大特点就是单线程,也就是同一时间内只能做一件 ...

  5. 浏览器交响曲 (一)浏览器中的js执行机制

    浏览器的工作原理 浏览器中的js执行机制 单线程的含义 同步.异步 完了吗?事情并非如此 所以执行的机制是怎样的?(宏任务.微任务) 个人理解: 希望过路大佬不吝赐教 浏览器中的js执行机制 今天在网 ...

  6. JavaScript中BOM简介及其对象、js执行机制

    目录 BOM简介 什么是BOM DOM和BOM的区别 BOM的构成 Window对象的常见事件 窗口加载事件 调整窗口大小事件 定时器函数 setTimeout( )定时器 停止setTimeout( ...

  7. JavaScript系列之JS执行机制

    文章の目录 1.JS是单线程 2.一个问题 3.同步和异步 3.1.同步 3.2.异步 3.3.同步和异步的本质区别 3.4.同步任务 3.5.异步任务 4.JS执行机制 5.示例 6.事件循环 7. ...

  8. JS 执行机制 详解(附图)

    一.JS是单线程 JS语言的一大特点就是单线程,也就是说,同一个时间只能做一件事.这是JS这门脚本语言诞生的使命所致--用来处理页面中用户的交互,以及操作DOM而诞生的. 单线程就意味着,所有任务需要 ...

  9. 理解js中的同步和异步

    首先要先了解下js单线程 一.为什么js是单线程? 其实,JavaScript的单线程,与它的用途是有很大关系,我们都知道,JavaScript作为浏览器的脚本语言,主要用来实现与用户的交互,利用Ja ...

最新文章

  1. Django 视图函数
  2. 什么是URL、绝对URL和相对URL
  3. django rest-framework 1.序列化 一
  4. 孔子绝粮于陈蔡子贡孔子问答节选(白话)
  5. AI入门:无门槛可以玩的神经网络
  6. P5470-[NOI2019]序列【模拟费用流】
  7. java 响应事件,用java响应颜色事件
  8. Android开发实现HttpClient工具类
  9. redis 入门总结
  10. 【学习笔记 1】集成电路发展及其设计制造流程(ICer必备)
  11. bldc不同载波频率_BLDC的双闭环老调不好,求帮助
  12. 网站如何快速变成灰色?,几行代码就搞定了!
  13. 走进tensorflow第六步——拟合一元二次函数
  14. List集合关于Stream的操作
  15. python与金融数据分析论文_python 金融大数据分析 pdf
  16. 解决 Performing stop of activity that is not resumed 报错!!
  17. USB3.0接口防静电及lay out设计
  18. 实习周记(第三周):忙碌
  19. 美国亚马逊即将开设第二家无人便利店
  20. WebRTC通话原理-SDP协议

热门文章

  1. Hexo 博客部署到阿里云ECS服务器(Ubuntu 20.04)和域名解析
  2. 【web前端特效源码】使用HTML5+CSS3制作一个会动的电脑桌面+昼夜变化动画效果~~适合初学者~超简单~ |前端开发
  3. 二叉树层次遍历:队列
  4. [Mac经验] Mac远程链接Windows 共享文件夹
  5. 七月集训(17,18)
  6. python窗口函数
  7. Python基础: repr函数和str的区别
  8. 正态分布高斯分布泊松分布_正态分布:将数据转换为高斯分布
  9. g_signal_connect_swapped与g_sign…
  10. r语言lm函数找不到对象_错误:在R中找不到函数....