手写promise

基本使用

1
2
3
4
5
6
7
8
9
10
11
12
13
const p1 = new promise((resovle,reject)=>{
resolve(value);//成功
reject(error);//失败
})//定义

p1.then(
(value)=>{
console.log("成功:"${value})
},
(err)=>{
console.log("失败:"${err})
}
);

开始手写前我们先得对promise对象,从架构上理解(图来源于网络)
promise架构图

如此便可以把基础的架构先准备好。

1
2
3
4
5
6
7
8
9
10
class Promise {

// 构造函数
// resolve
// reject
// then
// catch
// finally
// ...
}

接下来让我们一个一个实现它们。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
//起步构建
// 1.用类创建Promise,类中需要有个执行器executor
// 2.执行者中发生错误,交给异常状态处理
// 3.执行者中状态只能触发一次,状态触发一次之后,不能修改状态
// 4.执行者中的this,由调用执行者的作用域决定,因此我们需要将执行者中的this绑定为我们创建的Promise对象。
// 5.在构造函数中需要为Promise对象创建status和value记录Promise的状态和传值。
// 6.在构造函数中需要为Promise对象创建callbacks数组,用于存储then方法中的回调函数。
class MyPromise {
static PENDING = "pending";
static FULFILLED = "fulfilled";
static REJECTED = "rejected";

constructor(executor) {
this.status = MyPromise.PENDING; // 初始化状态为pending
this.value = null; // 初始化值为null
this.callbacks = []; // 初始化回调数组为空
try {
executor(this.resolve.bind(this), this.reject.bind(this)); // 执行executor函数,并传入resolve和reject函数作为参数
} catch (error) {
this.reject(error); // 如果executor函数发生错误,则将状态设置为rejected
}
}

resolve(value) {
if (this.status == MyPromise.PENDING) { // 只有在状态为pending时才能改变状态
this.status = MyPromise.FULFILLED; // 将状态设置为fulfilled
this.value = value; // 保存传入的值
setTimeout(() => {
this.callbacks.map((item) => {
item.onFulfilled(this.value); // 执行所有成功回调函数
});
});
}
}

reject(reason) {
if (this.status == MyPromise.PENDING) { // 只有在状态为pending时才能改变状态
this.status = MyPromise.REJECTED; // 将状态设置为rejected
this.value = reason; // 保存传入的原因
setTimeout(() => {
this.callbacks.map((item) => {
item.onRejected(this.value); // 执行所有失败回调函数
});
});
}
}

//开始写then方法
//1.then接收2个参数,一个成功回调函数,一个失败回调函数
//2.then中发生错误,状态为rejected,交给下一个then处理
//3.then返回的也是一个Promise
//4.then的参数值可以为空,可以进行传值穿透
//5.then中的方法是异步执行的
//6.then需要等promise的状态改变后,才执行,并且异步执行
//7.then是可以链式操作的
//8.then的onFulfilled可以用来返回Promise对象,并且then的状态将以这个Promise为准
//9.then的默认状态是成功的,上一个Promise对象的状态不会影响下一个then的状态
//10.then返回的promise对象不是then相同的promise
then(onFulfilled, onRejected) {
if (typeof onFulfilled != "function") { // 如果成功回调不是函数,则将其设置为默认的返回值函数
onFulfilled = (value) => value;
}

if (typeof onRejected != "function") { // 如果失败回调不是函数,则将其设置为默认的返回原因函数
onRejected = (reason) => reason;
}

let promise = new MyPromise((resolve, reject) => {
if (this.status == MyPromise.FULFILLED) { // 如果当前Promise状态为fulfilled,则异步执行成功回调
setTimeout(() => {
this.parse(promise, onFulfilled(this.value), resolve, reject);
});
}

if (this.status == MyPromise.REJECTED) { // 如果当前Promise状态为rejected,则异步执行失败回调
setTimeout(() => {
this.parse(promise, onRejected(this.value), resolve, reject);
});
}

if (this.status == MyPromise.PENDING) { // 如果当前Promise状态为pending,则将回调函数存储起来
this.callbacks.push({
onFulfilled: (value) => {
this.parse(promise, onFulfilled(value), resolve, reject);
},
onRejected: (reason) => {
this.parse(promise, onRejected(reason), resolve, reject);
},
});
}
});
return promise; // 返回新的Promise对象
}

//整理冗余代码
parse(promise, result, resolve, reject) {
if (promise == result) { // 如果返回的Promise与当前Promise相同,则抛出循环引用错误
throw new TypeError("Chaining cycle detected for promise");
}
try {
if (result instanceof MyPromise) { // 如果返回值是Promise对象,则继续调用then方法
result.then(resolve, reject);
} else {
resolve(result); // 否则,将返回值作为新Promise的成功值
}
} catch (error) {
reject(error); // 如果发生错误,则将错误作为新Promise的失败原因
}
}

//Promise的静态方法,resolve
static resolve(value) {
return new MyPromise((resolve, reject) => {
if (value instanceof MyPromise) { // 如果传入的值是Promise对象,则继续调用then方法
value.then(resolve, reject);
} else {
resolve(value); // 否则,将传入的值作为新Promise的成功值
}
});
}

//Promise的静态方法,reject
static reject(reason) {
return new MyPromise((resolve, reject) => {
reject(reason); // 将传入的原因作为新Promise的失败原因
});
}

//Promise的静态方法,all
static all(promises) {
let values = [];
return new MyPromise((resolve, reject) => {
promises.forEach((promise) => {
if (promise.status == MyPromise.FULFILLED) { // 如果有一个Promise状态为fulfilled,则将其值存入数组
values.push(promise.value);
} else if (promise.status == MyPromise.REJECTED) { // 如果有一个Promise状态为rejected,则直接将整个Promise设置为rejected
reject(promise.value);
}
if (values.length == promises.length) { // 如果所有Promise都已经fulfilled,则将数组作为新Promise的成功值
resolve(values);
}
});
});
}

//Promise的静态方法,race
static race(promises) {
return new MyPromise((resolve, reject) => {
promises.forEach((promise) => {
promise.then((value) => {
resolve(value); // 只要有一个Promise状态改变,则将其值作为新Promise的成功值
});
});
});
}

//Promise的静态方法,race
catch(onRejected) {
return this.then(null, onRejected); // catch方法实际上是then方法的简写,只传入失败回调
}
}

照抄的,自己如果真的遇见手写可能会有点蒙b!