Promise总结
次访问
Promise简介
Promise对象用于表示一个异步操作的最终状态(完成或失败),以及其返回的值。由浏览器直接支持。
打开Chrome的控制台输入new Promise(function () {});
后可以看到浏览器的Promise对象:
下面创建一个Promise:
1 | let promise = new Promise(function(resolve, reject) { |
传给new Promise作为参数的函数叫做executor。Promise创建后自动运行。
promise有两个内部变量:
1、state — 初始值pending, 会变成fulfilled或rejected。
2、result — 初始值undefined,代码运行后的任意值。
当executor运作完毕,会执行它两个参数中的一个函数:
resolve(value) - 代表executor运作结果是成功的,并且:
1、把state变成fulfilled;
2、把result变成value。
reject(error) - 代表executor运作出错,并且:
1、把state变成rejected;
2、把result变成error。
Promise状态是resolved或rejected时叫做settled。
上面说到executor运行完毕会执行resolve或reject,其实executor只会执行一次resolve或reject,并且result改变后不能再改变。resolve/reject只会接收1个参数,后续的都会被忽略。
1 | let promise = new Promise(function(resolve, reject) { |
demo
1、处理 rejection
有两种方式去处理 rejection
1 | let promise = new Promise((resolve, reject) => { |
1 | // 方式一 |
2、Unhandled rejections
发生错误时,Promise状态变成reject,execution跳转到最近的rejection handler,如果没有rejection handler,错误就会变成stuck。
比如:
1 | new Promise(function() { |
或者:
1 | // a chain of promises without .catch at the end |
大多数js引擎会全局处理这种错误,我们可以在console中看到。
3、触发Promise异常
- 主动调用 reject 方法
- 抛出异常(exception)
1 | new Promise((resolve, reject) => { |
4、链式调用
1 | new Promise((resolve, reject) => { |
5、.then/.catch是异步的
1 | console.log('javascript start'); |
1 | new Promise((resolve) => { |
构造函数中的executor执行是同步的,输出 a, 执行 resolve 函数,将 Promise 对象状态置为 resolved,输出 c。同时注册这个 Promise 对象的回调 then 函数。整个脚本执行完,stack 清空。event loop 检查到 stack 为空,再检查 microtask 队列中是否有任务,发现了 Promise 对象的 then 回调函数产生的 microtask,推入 stack,执行。输出 b,event loop的列队为空,stack 为空,脚本执行完毕。
microtask:在当前 task 执行完,准备进行 I/O,repaint,redraw 等原生操作之前,需要执行一些低延迟的异步操作(microtask),使得浏览器渲染和原生运算变得更加流畅。假如每执行一个异步操作都要重新生成一个 task,将提高宿主平台的负担和响应时间。所以,需要有一个概念,在进行下一个 task 之前,将当前 task 生成的低延迟的,与下一个 task 无关的异步操作执行完,这就是 microtask。
原生的setTimeout就算是将延迟设置为 0 也会有 4 ms 的延迟,会将一个完整的 task 放进队列延迟执行,而且每个 task 之间会进行渲染等原生操作。
Promise 所说的异步执行,只是将 Promise 构造函数中 resolve,reject 方法和注册的 callback 转化为 eventLoop的 microtask/Promise Job,并放到 Event Loop 队列中等待执行,也就是Javascript单线程中的“异步执行”。
Promise实现原理
自行阅读参考的后3个链接