一、首先需要区分几个概念:

1. 进程和线程的概念:

  进程:指在系统中运行的一个应用程序,目的就是担当分配系统资源(CPU时间、内存等)的基本单位

  线程:系统分配处理器时间资源的基本单元,建立在进程的基础上,一个进程至少要有一个线程。

2. 浏览器是多进程,多线程的,而JS是单线程的:

  打开一个浏览器Tab页签,会同时创建多个进程,主进程、网络进程、渲染进程、GPU进程...;

  而浏览器的内核就运行在渲染进程中,渲染进程会同时创建GUI渲染线程、JS引擎线程、事件触发线程、定时器触发线程、异步HTTP请求线程;

  其中JS引擎进程就是我们常说的JS是单线程的概念。

二、同步任务和异步任务

  同步任务:在主程序上按顺序执行的任务就叫做同步任务,只有上一个任务执行完毕后,才会执行下一个任务

  异步任务:未进入主程序,被放置在一个叫做任务队列中的程序中,常见的有回调函数中或者定时器中的任务。

  首先程序会去执行同步任务,同步任务全部执行完毕则去任务队列检查是否存在异步任务;

  注:如果执行中遇到定时器或者延时器,会启动定时线程进行计时监控,如果倒计时为0,则将回调函数中的任务塞

    入到异步队列当作宏任务执行,不是在一开始就塞入任务队列中

三、宏任务和微任务

  除了可以分为同步任务和异步任务外,为了更好的理解执行流程,还可以细化为宏任务和微任务;

  宏任务包含:主代码、setTimeout、setInterval、setImmediate、i/o操作(输入输出,比如读取文件操作、网络请求)、

           ui render(dom渲染,即更改代码重新渲染dom的过程)、异步ajax等

  微任务包含:Promise(then、catch、finally)、process.nextTick、Object.observe(⽤来实时监测js中对象的变化)、

        MutationObserver(监听DOM树的变化)

  注:new Promise(() => { ****})中的任务是宏任务、同步任务,只有.then\.finally\.catch中的任务才是微任务、异步任务

引擎在执行程序的顺序是宏任务-->微任务-->GUI渲染任务-->宏任务....;

  启动执行程序,JS引擎会把整个JS当作宏任务进入主程序开始执行,宏任务执行完成后,会去查看是否存在微任务并执行完毕,然后继续执行宏任务,

  由于主程序不知道是否存在微任务,所以每次宏任务执行完毕后都会去检查是否存在微任务,这种周而复始的过程就叫做事件循环。

四、示例说明

 1 console.log(1);
2 var timeout1 = setTimeout(() => {
3 console.log(2);
4 new Promise((resolve) => {
5 console.log(3);
6 resolve();
7 }).then(() => {
8 console.log(4);
9 })
10 })
11
12 new Promise((resolve) => {
13 console.log(5);
14 resolve();
15 }).then(() => {
16 console.log(6);
17 })
18
19 var timeout2 = setTimeout(() => {
20 console.log(7);
21 new Promise((resolve) => {
22 console.log(8);
23 resolve();
24 }).then(() => {
25 console.log(9);
26 })
27 })
28 console.log(10);

打印结果为:1  5  10  6  2  3  4  7  8  9;

过程详解:

1. 首先顺序执行第1行打印结果为:1;

2. 执行2-10行为异步任务,启动定时进程进行倒计时,但是不会立即添加异步任务到任务队列中

3. 执行12-17行,按照上文备注promise()中的方法是宏任务所以会顺序执行,同时打印出5, 其中.then是异步任务所以会添加到任务队列的微任务中.

4. 执行19-27行与第二步类似,启动定时进程进行倒计时

5. 执行28行打印结果为:10

6. 宏任务全部执行完毕后就会去任务队列中检查是否存在微任务并执行,打印结果为:6

7. 倒计时16ms左右结束时,按照代码的先后顺序首先将timeout1中的异步任务添加到任务队列

8. 将timeout1中的任务添加到主程序当作一个宏任务开始执行所以打印结果是:2, 3;然后将.then中的任务添加到微任务中,

  每个宏任务后都会执行一个事件循环检查,然后开始执行微任务,最终打印结果为:2,3,4

9. timeout2会重复执行7、8两步,打印结果为7,8,9

JS单线程的理解的更多相关文章

  1. 从浏览器多进程到JS单线程,JS运行机制的一次系统梳理

    前言 见解有限,如有描述不当之处,请帮忙及时指出,如有错误,会及时修正. ----------超长文+多图预警,需要花费不少时间.---------- 如果看完本文后,还对进程线程傻傻分不清,不清楚浏 ...

  2. 从浏览器多进程到JS单线程,JS运行机制最全面的一次梳理

    前言 来源:https://dailc.github.io/2018/01/21/js_singlethread_eventloop.html 见解有限,如有描述不当之处,请帮忙及时指出,如有错误,会 ...

  3. 【本周面试题】第2周 - js单线程和异步相关问题

    硬性知识点考察: 为什么js是单线程的? 因为js设计最初是为了操作dom而生,如果是多线程的,当多个线程同时修改一个dom时就会产生冲突,所以设计成单线程,一次只能做一件事. 既然是单线程为什么要有 ...

  4. angular.js的一点理解

    对angular.js的一点理解 2015-01-14 13:18 by MrGeorgeZhao, 317 阅读, 4 评论, 收藏, 编辑 最近一直在学习angular.js.不得不说和jquer ...

  5. 前端基本知识(三):JS的闭包理解

    JS闭包的理解 一.变量的作用域 二.如何从外部读取局部变量 三.什么是闭包 四.深入理解闭包 五.闭包的用途 六.使用闭包注意情况 七.JavaScript的垃圾回收机制 八.一些思考题 一.变量作 ...

  6. 前端基本知识(三):JS的闭包理解(第一个思考题有错误,已修改)

    JS闭包的理解 一.变量的作用域 二.如何从外部读取局部变量 三.什么是闭包 四.深入理解闭包 五.闭包的用途 六.使用闭包注意情况 七.JavaScript的垃圾回收机制 八.一些思考题 一.变量作 ...

  7. JS 单线程

    js单线程阻塞实例setTimeout(function () { while (true) { } }, 1000);setTimeout(function () { alert('end 2'); ...

  8. 37.js----浅谈js原型的理解

    浅谈Js原型的理解 一.js中的原型毫无疑问一个难点,学习如果不深入很容易就晕了!    在参考了多方面的资料后,发现解释都太过专业,对于很多还没有接触过面向对象    语言的小白来说,有理解不了里面 ...

  9. JS底层知识理解之执行上下文篇

    JS底层知识理解之执行上下文篇 一.什么是执行上下文(Execution Context) 执行上下文可以理解为当前代码的执行环境,它会形成一个作用域. 二.JavaScript引擎会以什么方式去处理 ...

  10. 用故事解析setTimeout和setInterval(内含js单线程和任务队列)

    区别: setTimeout(fn,t): 延迟调用,超过了时间就调用回调函数,返回一个id,使用clearTimeout(id)取消执行. 注意:取消了里面的回调函数就不执行了哦,而不是取消的时候就 ...

随机推荐

  1. JVM整理笔记

    1.JVM位置 JVM是作用在操作系统之上的,它与硬件没有直接的交互 2.JVM体系结构 3.类装载器ClassLoader 类装载器:负责加载class文件,class文件在文件开头有特定的文件标示 ...

  2. Kernel Memory 入门系列:快速开始

    Kernel Memory 入门:Quick Start 了解了用户问答和文档预处理的流程之后,我们就可以直接开始使用Kernel Memory了. 1. 安装 项目中只需要通过NuGet安装Micr ...

  3. 普冉PY32系列(十四) 从XL2400迁移到XL2400P

    目录 普冉PY32系列(一) PY32F0系列32位Cortex M0+ MCU简介 普冉PY32系列(二) Ubuntu GCC Toolchain和VSCode开发环境 普冉PY32系列(三) P ...

  4. 深入理解 Docker 核心原理:Namespace、Cgroups 和 Rootfs

    通过这篇文章你可以了解到 Docker 容器的核心实现原理,包括 Namespace.Cgroups.Rootfs 等三个核心功能. 如果你对云原生技术充满好奇,想要深入了解更多相关的文章和资讯,欢迎 ...

  5. postman——下载与安装

    一.postman是什么? 那么,Postman是个什么东东呢?Postman的官网上这么介绍它:"Modern software is built on APIs,Postman help ...

  6. TDD、BDD、ATDD都是什么、有什么区别?(下)

    在<TDD.BDD.ATDD都是什么.有什么区别?(下)>一文中,探讨了TDD.BDD和ATDD的概念.虽然TDD.BDD和ATDD都是软件开发中使用的测试方法,但它们在方法和重点上有所不 ...

  7. JavaFx之TableView表格添加按钮删除行(二十二)

    JavaFx之TableView表格添加按钮删除行(二十二) JavaFx之TableView添加按钮 JavaFx之TableView删除行 编写一个xml <?xml version=&qu ...

  8. C#中对比两个对象是否相等最佳实践,IEquatable和IEqualityComparer的差异

    前言 IEquatable<T> IEqualityComparer<T> 后言 参考 前言 IEquatable<T> 和 IEqualityComparer&l ...

  9. 斯坦福 UE4 C++ ActionRoguelike游戏实例教程 13.使用GameplayTag实现使用钥匙卡打开箱子

    斯坦福课程 UE4 C++ ActionRoguelike游戏实例教程 0.绪论 概述 本篇文章将会展示Gameplay另一个用法,也就是我们最常见的使用特定道具交互特定的机关.例如本文要实现的,获得 ...

  10. 2023-05-13:你现在手里有一份大小为 n x n 的 网格 grid, 上面的每个 单元格 都用 0 和 1 标记好了其中 0 代表海洋,1 代表陆地。 请你找出一个海洋单元格,这个海洋单元格

    2023-05-13:你现在手里有一份大小为 n x n 的 网格 grid, 上面的每个 单元格 都用 0 和 1 标记好了其中 0 代表海洋,1 代表陆地. 请你找出一个海洋单元格,这个海洋单元格 ...