JS JavaScript事件循环机制

区分进程和线程

进程是cpu资源分配的最小单位(系统会给它分配内存)

不同的进程之间是可以同学的,如管道、FIFO(命名管道)、消息队列

一个进程里有单个或多个线程

浏览器是多进程的,因为系统给它的进程分配了资源(cpu、内存)(打开Chrome会有一个主进程,每打开一个Tab页就有一个独立的进程)

浏览器的渲染进程是多线程的

1.GUI渲染线程

2.JS引擎线程

3.事件触发线程

4.定时触发器线程

5.异步HTTP请求线程

事件循环机制

上图解释:

同步和异步任务分别进入不同的执行"场所",同步的进入主线程,异步的进入Event Table并注册函数

当指定的事情完成时,Event Table会将这个函数移入Event Queue

当栈中的代码执行完毕,执行栈(call stack)中的任务为空时,就会读取任务队列(Event quene)中的事件,去执行对应的回调

如此循环,形成js的事件循环机制(Event Loop)

宏任务(macrotask)和微任务(microtask)

先看一段代码的执行结果:

console.log(‘script start‘);

setTimeout(function() {
  console.log(‘setTimeout‘);
}, 0);

Promise.resolve().then(function() {
  console.log(‘promise1‘);
}).then(function() {
  console.log(‘promise2‘);
});

console.log(‘script end‘);

执行结果: script start , script end , promise1 , promise2 , setTimeout

JS中分为两种任务类型:macrotaskmicrotask,在ECMAScript中,microtask称为jobs,macrotask可称为task

  • macrotask(又称之为宏任务),可以理解是每次执行栈执行的代码就是一个宏任务(包括每次从事件队列中获取一个事件回调并放到执行栈中执行)

    • 每一个task会从头到尾将这个任务执行完毕,不会执行其它
    • 浏览器为了能够使得JS内部task与DOM任务能够有序的执行,会在一个task执行结束后,在下一个 task 执行开始前,对页面进行重新渲染 (task->渲染->task->...
  • microtask(又称为微任务),可以理解是在当前 task 执行结束后立即执行的任务
    • 也就是说,在当前task任务后,下一个task之前,在渲染之前
    • 所以它的响应速度相比setTimeout(setTimeout是task)会更快,因为无需等渲染
    • 也就是说,在某一个macrotask执行完后,就会将在它执行期间产生的所有microtask都执行完毕(在渲染前)

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

  • macrotask:主代码块,setTimeout,setInterval等(可以看到,事件队列中的每一个事件都是一个macrotask)
  • microtask:Promise,process.nextTick等

补充:在node环境下,process.nextTick的优先级高于Promise,也就是可以简单理解为:在宏任务结束后会先执行微任务队列中的nextTickQueue部分,然后才会执行微任务中的Promise部分。

总结下运行机制:

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

如图:

原文地址:https://www.cnblogs.com/lhh520/p/10259129.html

时间: 01-11

JS JavaScript事件循环机制的相关文章

定时器运行原理 && javascript事件循环模型

定时器是我们经常使用的一个异步函数,它的用处十分广泛,比如图片轮播.各种小的动画.延时操作等等:定时器函数只有两个setTimeout.setInterval,这两个工作原理相同,唯一的区别是:setTimeout只执行一次,setInterval循环执行:通过以下实例看看对定时器原理掌握程度: 定时器3个实例 首先声明这三个实例输出皆不同,先思考输出结果,以及为何不同 实例一: console.log('test1') for(var i=0;i<10;i++){ setTimeout(()=

解析Javascript事件冒泡机制

本资源引自: 解析Javascript事件冒泡机制 - 我的程序人生 - 博客频道 - CSDN.NET http://blog.csdn.net/luanlouis/article/details/23927347 ----------------------------------------------------------------------------------------------------------------------------------------- 1.

javascript事件委托机制详解

以个人前端工作面试经历来看,javascript事件委托是问的最多的一类题目之一,熟悉事件委托能够了解你对于javascript的掌握程度. 面试官可能问一下问题,现在有5个li待办事件,需要实现当点击一个li时实现弹出该li的信息 <ul class="top"> <li>橘子</li> <li>香蕉</li> <li>苹果</li> <li>梨子</li> <li>

理解 node.js 的事件循环

node.js 的第一个基本观点是,I/O 操作是昂贵的: 目前的编程技术最大的浪费来自等待 I/O 操作的完成.有几种方法可以解决这些对性能的影响(来自Sam Rushing): 同步:依次处理单个请求. 优点:简单. 缺点:任何一个请求都会阻塞其余请求. 创建新进程:为每个请求创建一个进程处理 优点:容易. 缺点:扩展性不好,数百个连接意味着数百个进程.fork()是 Unix 程序员的锤子.因为它很有用,所有的问题都像是钉子.但这通常是多余的. 线程:为每个请求创建一个线程处理. 优点:容

解析Javascript事件冒泡机制(转) 本文转自:http://blog.csdn.net/luanlouis/article/details/23927347

本文转自:http://blog.csdn.net/luanlouis/article/details/23927347 1. 事件 在浏览器客户端应用平台,基本生都是以事件驱动的,即某个事件发生,然后做出相应的动作. 浏览器的事件表示的是某些事情发生的信号.事件的阐述不是本文的重点,尚未了解的朋友,可以访问W3school教程 进行了解,这将有助于更好地理解以下的内容 . 2. 冒泡机制 什么是冒泡呢? 下面这个图片大家应该心领神会吧,气泡从水底开始往上升,由深到浅,升到最上面.在上升的过程中

JavaScript:彻底理解同步、异步和事件循环(Event Loop) (转)

原文出处:https://segmentfault.com/a/1190000004322358 一. 单线程 我们常说"JavaScript是单线程的". 所谓单线程,是指在JS引擎中负责解释和执行JavaScript代码的线程只有一个.不妨叫它主线程. 但是实际上还存在其他的线程.例如:处理AJAX请求的线程.处理DOM事件的线程.定时器线程.读写文件的线程(例如在Node.js中)等等.这些线程可能存在于JS引擎之内,也可能存在于JS引擎之外,在此我们不做区分.不妨叫它们工作线程

JavaScript:同步、异步和事件循环

一. 单线程 我们常说“JavaScript是单线程的”. 所谓单线程,是指在JS引擎中负责解释和执行JavaScript代码的线程只有一个.不妨叫它主线程. 但是实际上还存在其他的线程.例如:处理AJAX请求的线程.处理DOM事件的线程.定时器线程.读写文件的线程(例如在Node.js中)等等.这些线程可能存在于JS引擎之内,也可能存在于JS引擎之外,在此我们不做区分.不妨叫它们工作线程. 二. 同步和异步 假设存在一个函数A: A(args...); 同步:如果在函数A返回的时候,调用者就能

javascript事件机制了解与深入

一.事件的捕获与冒泡 “DOM2级事件”规定的事件流包括三个阶段:事件捕获阶段.处于目标阶段和事件冒泡阶段.下面这个图能够很形象的解释(理解捕获和冒泡必不可少的图) 按照图我们编写了代码去验证下, <div id="parent"> <div id="child"> child </div> </div> <script type="text/javascript"> var p = d

node.js 回调函数、事件循环、EventEmitter ar

异步编程  node.js 编程的直接体现就是回调,异步编程依托于回调来实现: node使用了大量的回调函数,所有API都支持回调函数 .如读取文件等. 这里对不懂线程和异步和同步的稍微解释下这三个名词 . 线程 : 简单的说就是做一件事 . 即执行一段程序代码 .js引擎就是一个单线程 的 处理 方式 .单线程是说 同一时间只能做一件事 . 同步 :就是这件事必须要先做完前面的才能做后面的,否则后面的无法完成. 这就像我们的js代码会从上往下 运行 . 异步 :简单的说就是两个线程,你做你的,

node.js的作用、回调、同步异步代码、事件循环

http://www.nodeclass.com/articles/39274 一.node.js的作用 I/O的意义,(I/O是输入/输出的简写,如:键盘敲入文本,输入,屏幕上看到文本显示输出.鼠标移动,在屏幕上看到鼠标的移动.终端的输入,和看到的输出.等等) node.js想解决的问题,(处理输入,输入,高并发 .如 在线游戏中可能会有上百万个游戏者,则有上百万的输入等等)(node.js适合的范畴:当应用程序需要在网络上发送和接收数据时Node.js最为适合.这可能是第三方的API,联网设