手写一个Promise

尝试实现一个符合规范的 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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
const { count } = require('console')

const promisePractice = new Promise((resolve, reject) => {
setTimeout(() => {
return resolve(12)
}, 4000)
})
promisePractice
.then((data) => {
console.log(data)
})
.finally((data) => {
console.log(data)
})

console.log(Promise)

// 区分 resolve() 和 reject() 方法传入的值是 promise 和 then() 方法的返回值 是 promise 的情况

const PENDING = 'PENDING'
const FULLFILLED = 'FULLFILLED'
const REJECTED = 'REJECTED'

class PromiseClass {
constructor(fun) {
// 状态初始化
this._status = PENDING
// value
this._value = undefined
// 添加成功回调函数队列
this._fullfilledQueues = []
// 添加失败回调函数队列
this._rejectedQueues = []
if (typeof v !== 'function') throw new Error('must accept a function as a parameter')
try {
fun(this._resolve.bind(this), this._reject.bind(this))
} catch (error) {
this._reject(error)
}
}
_resolve(val) {
const run = () => {
if (this._status !== PENDING) return
// 依次执行成功队列中的函数,并清空队列
const runFullfilled = (value) => {
let cb
while ((cb = this._fullfilledQueues.shift())) {
cb(val)
}
}
// 依次执行失败队列中的函数,并清空队列
const runrejected = (error) => {
let cb
while ((cb = this._rejectedQueues.shift())) {
cb(error)
}
}

if (val instanceof PromiseClass) {
val.then(
(value) => {
this._value = value
this._status = FULLFILLED
runFullfilled(value)
},
(err) => {
this._value = err
this._status = REJECTED
runrejected(err)
}
)
} else {
this._value = val
this._status = FULLFILLED
runFullfilled(val)
}
}

// setTimeout(run,0)
setTimeout(() => run(), 0)
}
_reject(err) {
if (this._status !== PENDING) return

this._status = REJECTED
this._value = err
const run = () => {
let cb
while ((cb = this._rejectedQueues.shift())) {
cb(err)
}
}
// setTimeout(run,0)
setTimeout(() => run(), 0)
}
// then 方法必定返回一个 promise
then(onFullfilled, onRejected) {
const { _status, _value } = this
return new PromiseClass((onFullfilledNext, onRejectedNext) => {
// 封装成功时的回调函数
let fullfilled = (value) => {
try {
if (typeof onFullfilled !== 'function') {
onFullfilledNext(value)
} else {
let res = onFullfilled(value)
if (res instanceof PromiseClass) {
// 如果当前回调函数返回MyPromise对象,必须等待其状态改变后在执行下一个回调
res.then(onFullfilledNext, onRejectedNext)
} else {
// 否则会将返回结果直接作为参数,传入下一个then的Fulfilled回调函数,并立即执行下一个then的Fulfilled回调函数
onFullfilledNext(res)
}
}
} catch (e) {
onRejectedNext(e)
}
}
// 封装失败时的回调函数
let rejected = (err) => {
try {
if (typeof onRejected !== 'function') {
onRejectedNext(err)
} else {
let res = onRejected(err)
if (res instanceof PromiseClass) {
// 如果当前回调函数返回Promise对象,必须等待其状态改变后在执行下一个回调
res.then(onFullfilledNext, onRejectedNext)
} else {
// 否则会将返回结果直接作为参数,传入下一个then的rejected回调函数,并立即执行下一个then的rejected回调函数
onRejectedNext(res)
}
}
} catch (e) {
onRejectedNext(e)
}
}
switch (_status) {
case PENDING:
this._fullfilledQueues.push(onFullfilled)
this._rejectedQueues.push(onRejected)
break

case FULLFILLED:
fullfilled(_value)
break

case REJECTED:
rejected(_value)
break
}
})
}
catch(reject) {
return this.then(null, reject)
}
static resolve(val) {
if (val instanceof PromiseClass) {
return val
} else {
return new PromiseClass((resolve) => {
resolve(val)
})
}
}
static reject(err) {
return new PromiseClass((resolve, reject) => {
reject(err)
})
}
static all(list) {
return new PromiseClass((resolve, reject) => {
const values = []
count = 0
for (let [index, promise] of list.entires()) {
// 确保数组中的各项是 PromiseClass的实例,先调用 PromiseClass.resolve
this.resolve(promise).then(
(res) => {
values[index] = res
count++
// 所有状态都为 fullfilled 时返回的PromiseClass状态变成 fullfilled
if (count === list.length) resolve(values)
},
(err) => {
// 有一个被rejected时返回的MyPromise状态就变成rejected
reject(err)
}
)
}
})
}
static race(list) {
return new PromiseClass((resolve, reject) => {
for (let p of list) {
this.resolve(p).then(
(res) => {
resolve(res)
},
(err) => {
reject(err)
}
)
}
})
}
finally(cb) {
return this.then(
(value) => PromiseClass.resolve(cb()).then(() => value),
(reason) =>
PromiseClass.resolve(cb()).then(() => {
throw reason
})
)
}
}