-
Notifications
You must be signed in to change notification settings - Fork 0
/
promise.js
254 lines (236 loc) · 7.96 KB
/
promise.js
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
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
;(function (window) {
//定义状态的常量
const PENDING = 'pending'
const RESOLVED = 'resolved'
const REJECTED = 'rejected'
//自定义promise
function Promise(execute) {
//保存this的指向
const self = this
this.status = 'pending' //保存promise的状态,初始值为pending
this.data = undefined //给promise对象指定一个用于存储结果数据的属性
this.callback = [] //保存回调函数,结构为 {onResolved:function () {},onRejected:function () {}}
//成功的函数
function resolve(value) {
//状态只能改变一次
if (self.status !== PENDING) {
return
}
//改变状态
self.status = RESOLVED
//保存数据值
self.data = value
//判断callback中有没有存储回调函数
if (self.callback.length > 0) {
//异步执行
setTimeout(() => {
self.callback.forEach((callbacksObj) => {
//调用成功的回调函数
callbacksObj.onResolved() //{onResolved:function () {},onRejected:function () {}}
})
})
}
}
//失败的函数
function reject(reason) {
//状态只能改变一次
if (self.status !== PENDING) {
return
}
//改变状态
self.status = REJECTED
//保存数据值
self.data = reason
//判断callback中有没有存储回调函数
if (self.callback.length > 0) {
//异步执行
setTimeout(() => {
self.callback.forEach((callbacksObj) => {
//调用失败的回调函数
callbacksObj.onRejected()
})
})
}
}
//同步调用执行器函数
try {
execute(resolve, reject) //执行器函数有可能抛出异常,如果抛出异常,promise的状态变为rejected
} catch (error) {
reject(error)
}
}
//返回一个新的promise
Promise.prototype.then = function (onResolved, onRejected) {
onResolved =
typeof onResolved === 'function' ? onResolved : (value) => value //向下传递成功的value
//实现异常穿透的关键点 提取默认的失败的回调
onRejected =
typeof onRejected === 'function'
? onRejected
: (reason) => {
throw reason
} //向后传递失败的reason
//保存this的指向
const self = this
//then方法返回一个新的promise对象 执行成功或者失败的函数由上一个promise对象then方法指定回调函数执行的返回值决定
return new Promise((resolve, reject) => {
function handler(callback) {
//捕获异常
try {
//接受函数执行的返回值
const result = callback(self.data)
//根据返回值进行判断
//如果函数的返回值是一个promise
if (result instanceof Promise) {
// result.then((value) => {resolve(value)},(reason) => {reject(reason)})
//优化写法 因为resolve、reject本身就是一个函数接受一个实参
result.then(resolve, reject)
} else {
//成功的回调 value就是函数返回的值
resolve(result)
}
} catch (error) {
//如果程序执行异常,调用reject,状态变为rejected
reject(error)
}
}
//如果状态为pending,把回调函数保存到对象的callbacks属性中
//格式为{onResolved:function () {},onRejected:function () {}}
if (this.status === PENDING) {
this.callback.push({
onResolved() {
handler(onResolved)
},
onRejected() {
handler(onRejected)
},
})
} else if (this.status === RESOLVED) {
//如果为成功的状态 异步调用成功的函数
setTimeout(() => {
//新的promise执行成功的函数还是失败的函数由then中指定的回调函数的返回值决定:
/*
1.如果程序抛出异常,执行reject函数
2.如果返回的是一个promise,那么执行的结果就是这个promise的结果
3.返回的不是一个promise,那么就调用resolve函数,就是成功
*/
handler(onResolved)
})
} else {
//失败的状态
//如果为失败的状态 异步调用失败的函数
setTimeout(() => {
handler(onRejected)
})
}
})
}
//返回一个新的promise
Promise.prototype.catch = function (onRejected) {
return this.then(undefined, onRejected)
}
//返回一个成功的promise
Promise.resolve = function (value) {
//value可能是一个普通的值,或者是一个promise
return new Promise((resolve, reject) => {
//如果value是一个promise,调用.then获取结果
if (value instanceof Promise) {
value.then(
(value) => {
resolve(value)
},
(reason) => {
reject(reason)
}
)
} else {
//value是一个普通的值,那么就调用resolve成功函数
resolve(value)
}
})
}
//返回一个失败的promise
Promise.reject = function (reason) {
return new Promise((resolve, reject) => {
//将promise状态变为失败
reject(reason)
})
}
Promise.all = function (promises) {
//创建一个数组,用来保存成功的promise
let promiseCache = []
//定义计数器,用来保存成功的promise的数量
let resolveCount = 0
//返回一个新的Promise
return new Promise((resolve, reject) => {
//遍历 函数形参promises []
promises.forEach((promise, index) => {
Promise.resolve(promise).then(
(value) => {
resolveCount++ //成功的计数器+1
//将值放入 promiseCache数组中
promiseCache[index] = value
if (resolveCount === promises.length) {
resolve(promiseCache)
}
},
(reason) => {
//如果有一个失败,该promise就是失败的状态
reject(reason)
}
)
})
})
}
//race方法,
Promise.race = function (promises) {
//返回一个新的promise
return new Promise((resolve, reject) => {
//遍历promises数组 promise的状态只能修改一次,后面再调用的没有效果
promises.forEach((promise) => {
//遍历得到每一个promise,但是不一定全是promise,可能是一个数值,使用Promise.resolve方法进行包装
Promise.resolve(promise).then(
(value) => {
resolve(value)
},
(reason) => {
reject(reason)
}
)
})
})
}
/* 拓展方法 */
//返回一个promise对象,在指定的时间后成功状态 (拓展方法)
Promise.resolveDelay = function (value, time) {
//value可能是一个普通的值,或者是一个promise
return new Promise((resolve, reject) => {
setTimeout(() => {
//如果value是一个promise,调用.then获取结果
if (value instanceof Promise) {
value.then(
(value) => {
resolve(value)
},
(reason) => {
reject(reason)
}
)
} else {
//value是一个普通的值,那么就调用resolve成功函数
resolve(value)
}
}, time)
})
}
//返回一个Promise,在指定的时间后失败 (拓展方法)
Promise.rejectDelay = function (reason, time) {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(reason)
}, time)
})
}
//将promise函数挂载到window上
window.Promise = Promise
})(window)