文章目录
  1. 1. 执行栈
  2. 2. 宿主环境
  3. 3. 浏览器宿主环境中的5个线程
  4. 4. 事件队列
  5. 5. Promise

执行栈

所有的js代码都是在执行上下文中进行的。js中执行上下文:

  • 全局执行上下文,默认的,在浏览器中,windows是全局对象
  • 函数执行上下文,js函数每次被调用创建上下文

通常我们代码中不止一个上下文,所有的上下文会被放入执行栈中,如图

cs

上图我们执行的js全局代码先被放到执行栈中,当碰到函数执行,继续放到执行栈中,函数执行完,继续执行全局,最后输出a b

宿主环境

再说宿主环境前,我们先简单聊一聊javascript这门语言
JavaScript ( JS ) 是一种具有函数优先的轻量级,解释型或即时编译型的编程语言。虽然它是作为开发Web 页面的脚本语言而出名的,但是它也被用到了很多非浏览器环境中,例如 Node.js、 Apache CouchDB 和 Adobe Acrobat。JavaScript 是一种基于原型编程、多范式的动态脚本语言,并且支持面向对象、命令式和声明式(如函数式编程)风格。这里提到的浏览器、Node.js也就是宿主环境了

浏览器宿主环境中的5个线程

1.js引擎:负责执行执行栈的最顶部代码
2.GUI线程:负责渲染页面
3.事件监听线程:负责监听各种事件
4.记时线程:负责记时
5.网络线程:负责网络通信

事件队列

除了自定义函数以及全局的一些执行,还有一些比如microTask、计时器结束的回调、事件回调、http回调、Promise产生的回调。这些回调的处理程序会被添加到事件队列。事件队列在不同的宿主环境中有所差异,大部分宿主环境会将队列细分为两种
(

  • 宏队列:microTask、计时器结束的回调、事件回调、http回调
  • 微队列:Promise产生的回调

当执行栈清空时,js引擎首先会将微队列的所有任务放依次执行,如果没有微队列,依次执行宏队列

如图
cs1

当计时线程发现有需要处理的程序,在计时到达之后,会将处理程序加一个事件队列的内存,当js引擎发现,执行栈中没有了任何内容,会将事件队列的第一个函数加入到执行栈中执行。

Promise

Promise是异步编程的一种解决方案,比传统的解决方案–回调函数和事件–更合理和强大。ES6将其写进了语言标准,统一了用法,原生提供Promise对象

所谓Promise,简单来说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。

Promise对象有2个特点
1.对象的状态不受外界影响。有三种状态,pending(进行中)、fulfilled(已成功)、rejected(已失败)
2.一旦状态改变就不会在变。

ES6规定 Promise是一个构造函数,用来生成Promise实例

1
2
3
4
new Promise(function(resolve,reject){
console.log("123");
});
console.log("456")

Promise创建后立即执行,所有输出123 456

Promise 实例具有then方法,也就是说,then方法是定义在原型对象Promise.prototype上的。它的作用是为 Promise 实例添加状态改变时的回调函数。

then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。因此可以采用链式写法,即then方法后面再调用另一个then方法。

1
2
3
4
5
6
7
8
9
new Promise(function (resolve, reject) {
console.log("123");
setTimeout(() => {
resolve();
}, 0);
}).then(() => {
console.log("aaa");
});
console.log("456")

输出结果为123 456 aaa

Promise产生的回调会在微队列中,如图

如果所示,promise的回调会进入微队列,在执行栈为空的时候,优先从微队列拉去处理程序到执行栈执行,然后去宏队列拉去处理程序执行。
最后输出结果123 456 aaa zzz

文章目录
  1. 1. 执行栈
  2. 2. 宿主环境
  3. 3. 浏览器宿主环境中的5个线程
  4. 4. 事件队列
  5. 5. Promise