佳宸学习和分享笔记的地方

0%

实现promise A+

实现promise A+

promiseA+规范,研究了两天,看了几篇解析文章,跟着敲出来的,要是凭空自己写估计水平还没到,下面有我的解释

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
// promise的三个状态,pending => resolved or => reject, 不可逆
const PENDING = 'pending'
const RESOLVED = 'resolved'
const REJECTED = 'rejected'

// 传递一个fn执行器,在try中执行
function MyPromise (executor) {
// 防止this变向
const that = this
// 设开始状态为pending
that.state = PENDING
// 用于保存 resolve 或者 reject 中传入参数的值
that.value = null
// 保存then中的回调
that.resolvedCallbacks = []
// 失败的回调
that.rejectedCallbacks = []

function resolve (value) {
// 判断传入的值是否为 Promise 类型
if (value instanceof MyPromise) {
return value.then(resolve, reject)
}
// 保证异步执行顺序
setTimeout(() => {
if (that.state === PENDING) {
// 改pending状态为 resolve
that.state = RESOLVED
// 将传入的值赋值给 value
that.value = value
// 遍历回调执行数组
that.resolvedCallbacks.forEach(fn => fn(that.value))
}
})
}

// 同resolve
function reject (value) {
setTimeout(() => {
if (that.state === PENDING) {
that.state = REJECTED
that.value = value
that.rejectedCallbacks.forEach(fn => fn(that.value))
}
})
}

try {
executor(resolve, reject)
} catch (e) {
reject(e)
}
}

// then方法
MyPromise.prototype.then = function (onFulfilled, onRejected) {
const that = this
let promise2
// 解决没有传值的问题,当参数不是函数类型时,需要创建一个函数赋值给对应的参数
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value
onRejected =
typeof onRejected === 'function'
? onRejected
: reason => {
throw reason
}
if (that.state === PENDING) {
// 返回一个新的 promise 对象
return (promise2 = new MyPromise((resolve, reject) => {
// 往回调数组中 push 函数
that.resolvedCallbacks.push(() => {
// 执行函数中可能 报错 ,try catch 捕获
try {
const x = onFulfilled(that.value)
resolutionProcedure(promise2, x, resolve, reject)
} catch (r) {
reject(r)
}
})

that.rejectedCallbacks.push(() => {
try {
const x = onRejected(that.value)
resolutionProcedure(promise2, x, resolve, reject)
} catch (r) {
reject(r)
}
})
}))
}
if (that.state === RESOLVED) {
// onFulfilled(that.value)
return (promise2 = new MyPromise((resolve, reject) => {
setTimeout(() => {
//因为穿透值的缘故,在默认的跑出一个error后,不能再用下一个的reject来接受,只能通过try,catch
try {
const x = onFulfilled(that.value)
//递归 判断他们是否为promise对象
resolutionProcedure(promise2, x, resolve, reject)
} catch (reason) {
reject(reason)
}
})
}))
}
if (that.state === REJECTED) {
// onRejected(that.value)
return (promise2 = new MyPromise((resolve, reject) => {
setTimeout(() => {
try {
const x = onRejected(that.value)
resolutionProcedure(promise2, x, resolve, reject)
} catch (reason) {
reject(reason)
}
})
}))
}
}

function resolutionProcedure (promise2, x, resolve, reject) {
// 避免循环引用
if (x === promise2) {
return reject(new TypeError('循环引用'))
}
// 不是null ,是 对象 或 函数
if (x != null && (typeof x === 'object' || typeof x === 'function')) {
// called用于判断是否已经调用过函数
let called = false
try {
if (typeof x.then === 'function') {
// 参数 x 作为this指向
x.then.call(
x,
success => {
// 如果调用过 就直接返回了
if (called) return
called = true
// 递归调用 .then 中是否还有子 promise
resolutionProcedure(promise2, success, resolve, reject)
},
err => {
if (called) return
called = true
// 错误直接返回
reject(err)
}
)
} else {
resolve(x)
}
} catch (e) {
if (called) return
called = true
reject(e)
}
// 如果不是对象或函数将 x 传入resolve
} else {
resolve(x)
}
}