手写一个符合 promise/A+规范的 Promise
- 首先我们知道实现异步的方法 有 Promise,async、await ,回调,generator+co 库,这次我们主要讲的是 Promise
根据 promise/A+规范 我们可以了解到
- 解决(fulfill):指一个 promise 成功时进行的一系列操作,如状态的改变、回调的执行。虽然规范中用 fulfill 来表示解决,但在后世的 promise 实现多以 resolve 来指代之。
- 拒绝(reject):指一个 promise 失败时进行的一系列操作。
- 终值(eventual value):所谓终值,指的是 promise 被解决时传递给解决回调的值,由于 promise 有一次性的特征,因此当这个值被传递时,标志着 promise 等待态的结束,故称之终值,有时也直接简称为值(value)。
- 据因(reason):也就是拒绝原因,指在 promise 被拒绝时传递给拒绝回调的值。
通过上述文章可以基本了解一下 Promise 的基本内容
- 创建一个用 es5 或 es6 创建 Promise 类 这里 es6 的方式来创建 我们先来创建一个简单的 Promise 类
const {
isFun } = require("./util.js");
class MyPromise {
// 三种状态 等待, 解决 , 拒绝
static PENDING = "pending";
static FULFILLED = "fulfilled";
static REJECTED = "rejected";
constructor(callback) {
// 校验是否是一个函数
if (!isFun(callback)) {
throw new Error(`${
callback}不是一个函数`);
}
//改变this 为甚么要改变this 指向呢? 谁调用的 this在bro 中是window 在node中是undefined
this.initBind();
// 初始化状态值
this.initVal();
// 当 callback内部
callback(this.resolve, this.reject);
}
// 初始化绑定
initBind() {
this.resolve = this.resolve.bind(this);
this.reject = this.reject.bind(this);
}
// 初始化值
initVal() {
this.value = null; // 解决最终回调
this.err = null; // 拒接最终回调
this.status = MyPromise.PENDING; // 执行状态
}
// 解决
resolve(val) {
this.status = MyPromise.FULFILLED;
this.value = val;
}
// 拒因
reject(err) {
this.status = MyPromise.REJECTED;
this.err = err;
}
}
// 三种状态 等待, 解决 , 拒绝
exports.Promise = MyPromise;
- then 方法的实现
一个 promise 必须提供一个 then 用来返回解决,拒因
promise 的 then 方法接受两个参数:
onFulfilled ,onRejected
class MyPromise {
...
// then 方法
then(onFulfilled, onRejected) {
// onFulfilled是否是函数
if (!isFun(onFulfilled)) {
onFulfilled = function(val){
}
}
// onRejected是否是函数
if (!isFun(onRejected)) {
onRejected = function(err){
}
}
if (this.status === MyPromise.FULFILLED) {
onFulfilled(this.value);
}
if (this.status === MyPromise.REJECTED) {
onRejected(this.err);
}
}
}
- 接下来,我们来对比一下 原生 Promise,和自身定义的 MyPromise 执行顺序
console.log(1);
new MyPromise((resolve, reject) => {
console.log(2);
resolve("resolve");
}).then(
(res) => {
console.log(3)