手写Promise

  目录

模拟一个Promise功能

手写Promise

现在的异步基本上都是用Promise来实现的,用起来很方便,但是,Promise是怎么实现的呢,它的then回调是怎么工作的,带着这些疑问,决定自己实现一个Promise。
早在2年前,其实我就实现过一个Promise,不过那个原理比较笨,还用到了定时器循环,后来陆续看了些其他人的写法,还是有点没绕明白,这两天又看了向军老师的实现方式,觉得很好,自己也实现一下。
主要的难以理解的地方是then函数的写法,这个地方明白了整个Promise也就理解了。
代码如下:

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
class MyPromise {
// 等待状态
static PENDING = "pending";
// 成功状态
static FULFILLED = "fulfilled";
// 拒绝状态
static REJECTED = "rejected";
constructor(executor) {
// 默认状态是等待
this.status = MyPromise.PENDING;
// 成功值
this.value = null;
// 拒绝值
this.reason = null;
// then的回调数组
this.callbacks = [];
try {
executor(this.resolve.bind(this), this.reject.bind(this));
} catch (error) {
this.reject(error);
}
}
// 成功调用函数
resolve(value) {
if(this.status === MyPromise.PENDING) {
this.value = value;
this.status = MyPromise.FULFILLED;
setTimeout(()=> {
this.callbacks.forEach(item=> {
item.onFulfilled(this.value);
});
});
}
}
// 拒绝调用函数
reject(reason) {
if(this.status === MyPromise.PENDING) {
this.reason = reason;
this.status = MyPromise.REJECTED;
setTimeout(()=> {
this.callbacks.forEach(item=> {
item.onRejected(this.reason);
});
});
}
}
// then函数
then(onFulfilled, onRejected) {
if (typeof onFulfilled != "function") {
onFulfilled = () => this.value;
}
if (typeof onRejected != "function") {
onRejected = () => this.reason;
}
// 链式调用,返回一个MyPromise
const p = new MyPromise((resolve, reject)=> {
if(this.status === MyPromise.PENDING) {
this.callbacks.push({
onFulfilled: (value)=> {
let result = onFulfilled(value);
if(result instanceof MyPromise) {
result.then(resolve, reject);
}else {
resolve(result);
}
},
onRejected: (value)=> {
let result = onRejected(value);
if(result instanceof MyPromise) {
result.then(resolve, reject);
}else {
resolve(result);
}
}
});
}
if(this.status === MyPromise.FULFILLED) {
setTimeout(()=> {
let result = onFulfilled(this.value);
if(result instanceof MyPromise) {
result.then(resolve, reject);
}else {
resolve(result);
}
});
}
if(this.status === MyPromise.REJECTED) {
setTimeout(()=> {
let result = onRejected(this.reason);
if(result instanceof MyPromise) {
result.then(resolve, reject);
}else {
resolve(result);
}
});
}
});
return p;
}
// MyPromise.resolve方法
static resolve(value) {
return new MyPromise((resolve, reject)=> {
if(value instanceof MyPromise) {
value.then(resolve, reject);
}
resolve(value);
});
}
// MyPromise.reject方法
static reject(reason) {
return new MyPromise((resolve, reject)=> {
reject(reason);
});
}
// MyPromise.all方法
static all(promises) {
return new MyPromise((resolve, reject)=> {
let values = [];
promises.forEach(item => {
item.then(
value=> {
values.push(value);
if(values.length === promises.length) {
resolve(values);
}
},
reason=> {
reject(reason);
}
);
});
});
}
// MyPromise.race方法
static race(promises) {
return new MyPromise((resolve, reject)=> {
promises.forEach(item => {
item.then(
value=> {
resolve(value);
},
reason=> {
reject(reason);
}
);
});
});
}
}

demo代码点这里