说一说Promise的实现原理
# 上代码
class Promise {
constructor(params) {
//初始化state为pending
this.state = 'pending';
//成功的值,返回一般都是undefined
this.value = undefined;
//失败的原因,返回一般都是undefined
this.reason = undefined;
//成功执行函数队列
this.onResolvedCallbacks = [];
//失败执行函数队列
this.onRejectedCallbacks = [];
//success
let resolve = value => {
if (this.state === 'pending') {
//state change
this.state = 'fulfilled';
//储存成功的值
this.value = value;
//一旦成功,调用函数队列
this.onResolvedCallbacks.forEach(fn => fn());
}
};
//error
let reject = reason => {
if (this.state === 'pending') {
//state change
this.state = 'rejected';
//储存成功的原因
this.reason = reason;
//一旦失败,调用函数队列
this.onRejectedCallbacks.forEach(fn => fn());
}
};
try {
params(resolve, reject);
} catch (err) {
reject(err);
}
}
then(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
onRejected = typeof onRejected === 'function' ? onRejected : err => {
throw err
};
let promise2 = new Promise((resolve, reject) => {
//当状态是fulfilled时执行onFulfilled函数
if (this.state === 'fulfilled') {
//异步实现
setTimeout(() => {
try {
let x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
};
//当状态是rejected时执行onRejected函数
if (this.state === 'rejected') {
//异步实现
setTimeout(() => {
try {
let x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
};
//当状态是pending时,往onFulfilledCacks、onRejectedCacks里加入函数
if (this.state === 'pending') {
this.onResolvedCallbacks.push(() => {
//异步实现
setTimeout(() => {
try {
let x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
});
this.onRejectedCallbacks.push(() => {
//异步实现
setTimeout(() => {
try {
let x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0)
});
};
});
return promise2;
}
catch(fn) {
return this.then(null, fn);
}
}
function resolvePromise(promise2, x, resolve, reject) {
//循环引用报错
if (x === promise2) {
return reject(new TypeError('Chaining cycle detected for promise'));
}
//防止多次调用
let called;
//判断x
if (x != null && (typeof x === 'object' || typeof x === 'function')) {
try {
let then = x.then;
if (typeof then === 'function') {
then.call(x, y => {
if (called) return;
called = true;
resolvePromise(promise2, y, resolve, reject);
}, err => {
if (called) return;
called = true;
reject(err);
})
} else {
resolve(x);
}
} catch (e) {
if (called) return;
called = true;
reject(e);
}
} else {
resolve(x);
}
}
//resolve方法
Promise.resolve = function (val) {
return new Promise((resolve, reject) => {
resolve(val)
});
}
//reject方法
Promise.reject = function (val) {
return new Promise((resolve, reject) => {
reject(val);
});
}
const test = new Promise((res, rej) => {
setTimeout(() => {
res('resolve after 2000ms');
}, 2000)
})
test.then(res => {
console.error('res: ', res); // res: resolve after 2000ms
})
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
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
# 参考文章链接
手把手一行一行代码教你“手写Promise“,完美通过 Promises/A+ 官方872个测试用例 (opens new window)
Promise不会??看这里!!!史上最通俗易懂的Promise!!! (opens new window)