es6版promise

es6版Promise

用法

1
2
3
4
5
6
new Promise(function(resolve, reject) {
resolve('resolve')
})
.then(function(result) {
console.log(result) // resolve
})

Promise是一个构造函数,接受一个函数作为参数

这个函数接受两个参数:
(1) resolve 成功的时候返回的数据 (履行承诺)
(2) reject 失败的时候返回的数据 (拒绝承诺)

Promise原型方法

(1) then注册成功后的回调
(2) catch注册失败后的回调

上源代码——由于使用es6所以用babel,点击看编译过的代码

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
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
class util {
static isFunction(value) {
return typeof value === 'function'
}

static isArray(value) {
return Array.isArray(value)
}
}

/**
* Promise
* @constructor
*/
class Promise extends util {
constructor(executor) {
/**
* 继承绑定,作为context调用父类的constructor
*/
super(executor)

if (!Promise.isFunction(executor)) throw new TypeError('参数必须是一个函数')
/**
* @description
* 状态分为 PENDING 可以过度到RESOLVED或REJECTED
* RESOLVED
* REJECTED
* @type {string}
* @private
*/
this._status = 'PENDING'
/**
* 正确值
* @type {Object}
* @private
*/
this._value = Object.create(null)
/**
* 错误值
* @type {Object}
* @private
*/
this._reason = Object.create(null)
/**
* 储存错误回调
* @type {Array}
* @private
*/
this._rejecteds = []
/**
* 正确回调的方法集
* @type {Array}
* @private
*/
this._deferreds = []
/**
* 在class中 constructor里面的函数无法直接访问this
* 为了形成private,所以不放外面
* @type {Promise}
* @private
*/
let _this = this

/**
* 执行承诺的函数
* @param value
*/
function resolve(value) {
/**
* 异步,为了让then先执行,注册进回调
*/
setTimeout(() => {
try {
if (_this._status === 'PENDING') {
_this._status = 'RESOLVED'
_this._value = value
/**
* 循环执行所有的回调
*/
_this._deferreds.forEach((deferred) => {
deferred(value)
})

}
} catch (e) {
reject(e)
}

})
}

function reject(reason) {
setTimeout(() => {
try {
if (_this._status === 'PENDING') {
_this._status = 'REJECTED'
_this._reason = reason

_this._rejecteds.forEach((rejected) => {
rejected(reason)
})
}
} catch (e) {
reject(e)
}
})
}

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

}

/**
* resolve方法
* @example Promise.resolve('test').then(function(result){ result // test })
* @param value
* @returns {Promise}
*/
static resolve(value) {
return new Promise((resolve, reject) => {
resolve(value)
})
}

/**
* all方法 当需要许多promise一起执行的时候用,最后返回一个存有所有promise返回值的数组
* 当一个promise reject掉了,认为此all方法执行失败,进入reject
* @param promises
* @returns {Promise}
*/
static all(promises) {
if (!Promise.isArray(promises)) throw new TypeError('promises 必须是一个数组')

/**
* 返回一个Promise
*/
return new Promise((resolve, reject) => {
let result = [],
len = promises.length

/**
* 将所有的返回值存储起来
* @param value
*/
function resolveAll(value) {
result.push(value)

if (--len === 0) {
resolve(result)
}
}

promises.forEach(function (promise) {
/**
* 将成功后的加入result数组
* 一旦有一个失败,则直接返回失败
*/
promise.then(resolveAll, reject)
})

})
}

/**
* 方便使用,封装catch方法
* @param onRejected
*/
catch(onRejected) {
this.then(null, onRejected)
}

/**
* 重点方法,then
* @param onFulfilled
* @param onRejected
* @returns {Promise}
*/
then(onFulfilled, onRejected) {
/**
* 每次执行then都会返回一个promise供链式调用
*/
return new Promise((resolve, reject) => {
let returnedValue = Object.create(null)
/**
* 如果是RESOLVED状态说明执行了过resolve函数,this.value是有值的
* e.g. Promise.resolve('resolve').then(function(result){})
* 最主要看onFulfilled返回值是什么
*/
/**
* _RESOLVED
* @param value
* @private
*/
function _RESOLVED(value) {
/**
* 取得onFulfilled的返回值,判断是否返回一个promise
* 回调方式的then
* @example
* new Promise(function(resolve, reject){
* resolve('test')
* })
* .then(function(result){
* return new Promise(function(resolve, reject){
* resolve(result + 'test')
* })
* .then()
* })
*/
returnedValue = Promise.isFunction(onFulfilled) && onFulfilled(value) || value

try {
if (returnedValue && returnedValue instanceof Promise) {
returnedValue.then((value) => {
resolve(value)
}, (reason) => {
reject(reason)
})
} else {
resolve(returnedValue)
}

} catch (e) {
reject(e)
}
}

/**
* 失败的错误
* @param reason
* @private
*/
function _REJECTED(reason) {
returnedValue = Promise.isFunction(onRejected) && onRejected(reason) || reason

reject(returnedValue)
}

/**
* 直接调用resolve的情况
* @example
* Promise.resolve('test')
* .then(function() {})
*/

if (this._status === 'RESOLVED') {
_RESOLVED(this._value)

} else if (this._status === 'REJECTED') {
_REJECTED(this._reason)

} else if (this._status === 'PENDING') {
/**
* e.g. new Promise().then(function(result){})
*/
this._deferreds.push(_RESOLVED)

this._rejecteds.push(_REJECTED)
}

})

}

}
/**
* 将类返回,外面用babel编译
* @type {Promise}
*/
module.exports = Promise