js运行机制及异步编程(二)

news/2024/11/9 17:37:58
上一篇文章主要整理了一下js引擎是如何工作的,这篇文章主要整理js的事件循环Event loop,以及异步编程的原理

事件循环Event loop

之前文章中有讲到js是单线程的,而浏览器渲染内核包含多个线程的,和js代码部分相关的线程有如下几个:

  1. js引擎线程
  2. 处理ajax请求的线程,
  3. 处理DOM事件的线程,
  4. 定时器,
  5. 读写文件的线程(Node.JS)等
因为JS是单线程的,这是从JS引擎的角度来看的,所谓的单线程就是指在JS引擎中负责解释和执行JS代码的线程只有一个: 主线程

js分为同步任务和异步任务,同步任务都在主线程上执行,就形成一个执行栈,主线程之外,事件触发线程管理着一个任务队列,只要异步任务有了运行结果,就在任务队列中放置一个事件。一旦执行栈中所有的同步任务执行完毕(此时js引擎空闲),系统就会读取任务队列,将可运行的异步任务添加到可执行栈中,开始执行。

clipboard.png

JS的执行机制就是一个主线程 + 一个任务队列。同步任务就是放在主线程上执行的任务,异步任务就是放在任务队列的任务。所有的同步任务都在主线程执行,这构成了一个执行栈,异步任务有了运行结果会在任务队列中放置一个事件,比如定时2秒,到2秒后才能放进任务队列(callback放进任务队列,而不是setTimeout函数放进队列)。

事件循环(Event Loop)—— 脚本运行时,先依次运行执行栈,然后从队列中提取事件来运行任务队列中的任务,这个过程是不断重复的。所以叫事件循环(Event Loop)。

macrotask和microtask

上述js运行的机制主要说明的是es5,而es6的出现及普及,又有了新的概念,promise,它的出现,进一步,JS中分为两种任务类型:macrotask和microtask,在ECMAScript中,microtask称为jobs,macrotask可称为task。

clipboard.png

分别很么样的场景会形成macrotask和microtask呢?

  • macrotask:主代码块,setTimeout,setInterval, setImmediate, I/O, UI rendering. 等(可以看到,事件队列中的每一个事件都是一个macrotask)
  • microtask: process.nextTick, Promise(原生),Object.observe,MutationObserver
在node环境下,process.nextTick的优先级高于Promise,也就是可以简单理解为:在宏任务结束后会先执行微任务队列中的nextTickQueue部分,然后才会执行微任务中的Promise部分。

总结下运行机制:

  • 执行一个宏任务(栈中没有就从事件队列中获取)
  • 执行过程中如果遇到微任务,就将它添加到微任务的任务队列中
  • 宏任务执行完毕后,立即执行当前微任务队列中的所有微任务(依次执行)
  • 当前宏任务执行完毕,开始检查渲染,然后GUI线程接管渲染
  • 渲染完毕后,JS线程继续接管,开始下一个宏任务(从事件队列中获取)

案例说明

案例1:

setImmediate(function(){
    console.log(1);
},0);
setTimeout(function(){
    console.log(2);
},0);
new Promise(function(resolve){
    console.log(3);
    resolve();
    console.log(4);
}).then(function(){
    console.log(5);
});
console.log(6);
process.nextTick(function(){
    console.log(7);
});
console.log(8);

根据js的运行原理解释上面代码的执行顺序:

第一步 script整体代码被执行,执行过程为
创建setImmediate macro-task
创建setTimeout macro-task
创建micro-task Promise.then 的回调,并执行script console.log(3); resolve(); console.log(4); 此时输出3和4,虽然resolve调用了,执行了但是整体代码还没执行完,无法进入Promise.then 流程。
console.log(6)输出6
process.nextTick 创建micro-task
console.log(8) 输出8
第一个过程过后,已经输出了3 4 6 8

第二步 由于其他micro-task 的 优先级高于macro-task。

此时micro-task 中有两个任务按照优先级process.nextTick 高于 Promise。 
所以先输出7,再输出5

第三步 micro-task 任务列表已经执行完毕,家下来执行macro-task. 由于setTimeout的优先级高于setIImmediate,所以先输出2,再输出1。

参考:https://blog.csdn.net/gy_u_yg...
https://blog.csdn.net/m0_3775...


http://www.niftyadmin.cn/n/1934967.html

相关文章

操作系统 Linux ex1 note

ctrl alt T 命令行 ctrl alt F7 ctrl alt F1-6 ls 列出所有文件 / 根目录 ~ /home/username cd 切换路径 . 当前目录 .. 上级目录 mkdir B 创建文件夹 nano sum.c 使用nano编辑指定文件,若不存在则自动创建。 cat sum.c 查看指定文件,在控制台显示…

DNN:基于Keras对手写数字的识别

DNN:基于Keras对手写数字的识别Keras和TensorFlow的安装及常见故障处理Keras和TensorFlow的安装常见故障处理编程实现运行结果Keras和TensorFlow的安装及常见故障处理 Keras和TensorFlow的安装 1、在anaconda prompt中输入conda create -n keras创建keras环境 2、…

作为大众熟知的电商应用,京东如何构建风控体系架构?

作为大众熟知的电商应用,京东是如何构建坚挺的风控体系架构?如何优化数据的计算和存储?如何基于设备做智能识别的?本文由京东技术专家王美青对以上问题进行解读。 风控技术体系介绍 风控技术架构 上图是风控技术架构图&#xff0c…

jquery作业

1. 通过jquery动态的创建一个表格,随机生成(id自增,name随机2-3个中文汉字(10个姓,20个名字),age随机100以内整数)大于50小于100行的数据(用户对象:id,name,age&#xff…

二次冲刺站立会议八

今天我们找到了音乐素材(徐梦圆 - christmas),并添加在了我们的游戏中。我添加音乐。 代码如下 SoundPlayer s new SoundPlayer("C:\Users\lenovo\Desktop\趣拼图\音乐\徐梦圆 - christmas.wav"); 转载于:https://www.cnblogs.com…

消息队列之kafka(基础介绍)

一、关于JMS 1. JMS 的基础 JMS是Java提供的一套技术规范。即Java消息服务(Java message service)。应用程序接口。是一个Java平台中关于面向消息中间件的API。用于在两个应用程序之间或者分布式系统中发送消息,进行异步通信。Java消息服务是…

如何快速打造一款高清又极速的短视频APP?

2019独角兽企业重金招聘Python工程师标准>>> 整个短视频的市场规模一直在增长,网络数据显示2018年已经突破100亿大关,在2019年预测将超过200亿。纵观行业,在生活资讯、美食、搞笑、游戏、美妆等领域,短视频流量巨大但竞…

Java中监控文件变化的多种方案

一、使用Apache.Common.io库 package yungoal.huafeng.utils.files;import com.sun.deploy.util.SyncFileAccess; import org.apache.commons.io.monitor.FileAlterationListenerAdaptor; import org.apache.commons.io.monitor.FileAlterationMonitor; import org.apache.comm…