浏览器中js执行机制学习笔记

0.0772019.05.15 20:56:37字数 872阅读 291

同步任务

当一个脚本第一次执行的时候,js引擎会解析这段代码,并将其中的同步代码按照执行顺序加入执行栈中,然后从头开始执行。如果当前执行的是一个方法,那么js会向执行栈中添加这个方法的执行环境,然后进入这个执行环境继续执行其中的代码。当这个执行环境中的代码 执行完毕并返回结果后,js会退出这个执行环境并把这个执行环境销毁,回到上一个方法的执行环境。这个过程反复进行,直到执行栈中的代码全部执行完毕。

 
call stack

这个同步代码的执行过程可以是无限进行下去的,除非发生了栈溢出,即超过了所能使用内存的最大值。

异步任务

js引擎遇到一个异步事件后并不会一直等待其返回结果,而是会将这个事件挂起,继续执行执行栈中的其他任务。当一个异步事件返回结果后,js会将这个事件加入与当前执行栈不同的另一个队列,我们称之为事件队列。被放入事件队列不会立刻执行其回调,而是等待当前执行栈中的所有任务都执行完毕, 主线程处于闲置状态时,主线程会去查找事件队列是否有任务。如果有,那么主线程会从中取出排在第一位的事件,并把这个事件对应的回调放入执行栈中,然后执行其中的同步代码...如此反复

 
image.png

事件队列

我们先看两个实验

// 实验一
console.log('进入页面') setTimeout(() => {
console.log('setTimeout1')
}, 0)
new Promise((resolve) => {
console.log('promise')
setTimeout(() => {
console.log('setTimeout2')
resolve()
}, 0)
}).then(() => {
console.log('then')
})
console.log('代码执行结束') /* 打印结果
进入页面
promise
代码执行结束
setTimeout1
setTimeout2
then
*/

  

// 实验二
console.log('进入页面') setTimeout(() => {
console.log('setTimeout1')
}, 0)
new Promise((resolve) => {
console.log('promise')
resolve()
}).then(() => {
console.log('then')
})
console.log('代码执行结束') /*打印结果
进入页面
promise
代码执行结束
then
setTimeout1
*/

  

上面的两个demo中,demo2里在Promise里使用了setTimeout包了一层。造成then方法中的回调函数执行顺序稍有不同。一个在setTimeout之后,一个在setTimeou之前。为什么会造成这样的结果?

因为事件分为 macro-taskmicro-task。不同的事件会进入不同的队列。
也就是说事件队列对应的也有两个,macro queue和 micro queue

  • macro-task(宏任务):包括整体代码script,setTimeout,setInterval
  • micro-task(微任务):Promise,process.nextTick

上文中提到当主线程闲置后,会去事件队列中查找执行回调函数,这个是有一个先后策略的,先micro queuemacro queue。而这里的promise中只有在执行了resolve()后才会向micro queue中push在then方法里写的回调函数。这也是上边两个实验中console.log('then')执行顺序不同的原因,下面是详细的执行顺序:

实验1:
// 主线程开始执行同步代码
进入页面
//遇到setTimeout1异步挂起,接着执行同步代码
promise
//遇到setTimeout2异步挂起,接着执行同步代码
代码执行结束
// 同步代码执行完毕,主线程闲置,检查micro queue为空,检查macro queue 有两个回调函数
setTimeout1
setTimeout2
//执行了resolve(),向micro queue中push回调函数
//同步代码执行完毕,主线程闲置检查micro queue,执行里边的回调函数
then

  

实验2:
// 主线程开始执行同步代码
进入页面
//遇到setTimeout1异步挂起,接着执行同步代码
promise
//执行了resolve(),向micro queue中push回调函数
代码执行结束
// 同步代码执行完毕,主线程闲置,检查micro queue发现有回调函数执行
then
// 同步代码执行完毕, 主线程闲置, 检查micro queue为空,检查macro queue发现有回调函数并执行
setTimeout1

  

总结

不同类型的任务会进入对应的Event Queue,比如setTimeout和setInterval会进入相同的Event Queue。

事件循环的顺序,决定js代码的执行顺序。进入整体代码(宏任务)后,开始第一次循环。接着执行所有的微任务。然后再次从宏任务开始,找到其中一个任务队列执行完毕,再执行所有的微任务。

 

浏览器中js执行机制学习笔记的更多相关文章

  1. js执行顺序——学习笔记

    我们知道有个全局的 window对象,js的一切皆window上的属性和方法.window上有个window.document属性,记录了整个html的dom树,document是顶层. body 和 ...

  2. JS 执行机制笔记

        js同步和异步同步 前一个任务结束以后再执行下面一个任务,程序的执行顺序与任务的排列顺序是一致的 同步任务都在主线程上执行,形成一个执行线 异步 前一个任务没结束之前程序还可以执行别的任务 j ...

  3. JS学习笔记:(三)JS执行机制

    首先我们先明确一点:JavaScript是一门单线程语言.单线程也就是说同一时间只能执行一个任务,所有的任务都必须排队顺序执行.那么如果一个任务耗时很长,阻塞了其它任务的执行,就会给用户造成不友好的体 ...

  4. JS执行机制详解,定时器时间间隔的真正含义

     壹 ❀ 引 通过结果倒推过程是我们常用的思考模式,我在上一篇学习promise笔记中,有少量关于promise执行顺序的例子,通过倒推,我成功让自己对于js执行机制的理解一塌糊涂,js事件机制,事件 ...

  5. Underscore.js 源码学习笔记(下)

    上接 Underscore.js 源码学习笔记(上) === 756 行开始 函数部分. var executeBound = function(sourceFunc, boundFunc, cont ...

  6. Underscore.js 源码学习笔记(上)

    版本 Underscore.js 1.9.1 一共 1693 行.注释我就删了,太长了… 整体是一个 (function() {...}());  这样的东西,我们应该知道这是一个 IIFE(立即执行 ...

  7. JUC.Lock(锁机制)学习笔记[附详细源码解析]

    锁机制学习笔记 目录: CAS的意义 锁的一些基本原理 ReentrantLock的相关代码结构 两个重要的状态 I.AQS的state(int类型,32位) II.Node的waitStatus 获 ...

  8. js执行机制

    js是单线程的,为什么可以执行异步操作呢? 这归结与浏览器(js的宿主环境)通过某种方式使得js具备了异步的属性. 区分进程和线程: 进程:正在运行中的应用程序.每个进程都自己独立的内存空间.例如:打 ...

  9. 纯JS实现KeyboardNav(学习笔记)二

    纯JS实现KeyboardNav(学习笔记)二 这篇博客只是自己的学习笔记,供日后复习所用,没有经过精心排版,也没有按逻辑编写 这篇主要是添加css,优化js编写逻辑和代码排版 GitHub项目源码 ...

随机推荐

  1. Java(四)输出和输入函数

    介绍一下Java里简单常用的输入输出方法. Java的输出函数很简单,直接调用System类的out对象的print函数即可. 代码: System.out.print(a);//输出变量a的值 Sy ...

  2. 多线程模式下高并发的环境中唯一确保单例模式---DLC双端锁

    DLC双端锁,CAS,ABA问题 一.什么是DLC双端锁?有什么用处? 为了解决在多线程模式下,高并发的环境中,唯一确保单例模式只能生成一个实例 多线程环境中,单例模式会因为指令重排和线程竞争的原因会 ...

  3. PAT (Advanced Level) Practice 1011 World Cup Betting (20 分) (找最值)

    With the 2010 FIFA World Cup running, football fans the world over were becoming increasingly excite ...

  4. FHQTreap刷题记录

    分裂:如图,按值分裂,u比k大则切黄色的一

  5. React Hooks 笔记1

    useState const [state, setSate] = useState(initialState) 特征: setState 标识稳定,组件重新渲染时不会变化,useState 返回的第 ...

  6. Chrome 浏览器相关

    ********* 问题 ********* localhost 通常会使用加密技术来保护您的信息.Google Chrome 此次尝试连接到 localhost 时,此网站发回了异常的错误凭据.这可 ...

  7. ActiveMQ注意事项

    1.消费者在消费数据的过程当中报错,那么就会自动重试        2.如果消费者报错,会自动重试,但是数据已经真实拿到,可能会造成重复消费,幂等性问题            思路,每一次监听到数据后 ...

  8. Linux C语言 文件操作

    打开函数 fopen 的原型如下. FILE * fopen(char *filename, char *mode); 返回值:打开成功,返回该文件对应的 FILE 类型的指针:打开失败,返回 NUL ...

  9. NSSM 将jar 安装成windows服务

    1.下载 nssm (下载地址: http://www.nssm.cc/release/nssm-2.24.zip ) 2.将打包好的jar包放到一个文件夹中,编写run.bat文件,run.bat内 ...

  10. 二叉树(5)HuffmanTree

    构建一棵 HuffmanTree. 测试代码 main.cpp: #include <iostream> #include "HuffmanTree.h" using ...