-
Notifications
You must be signed in to change notification settings - Fork 0
/
promise.js
111 lines (100 loc) · 3.16 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
class MyPromise {
constructor(executor) {
let resolve = this._resolveOrReject.bind(this, 'resolved')
let reject = this._resolveOrReject.bind(this, 'rejected')
this._status = 'pending'
this._handerAtPending = []
try {
executor(resolve, reject)
} catch (e) {
this._value = e
this._status = 'rejected'
}
}
_resolveOrReject(which, val) {
if (this._status !== 'pending') {
return
}
if (val instanceof MyPromise && which === 'resolved') {
let copyStat = () => {
this._value = val._value
this._status = val._status
this._thenHandler && this._thenHandler()
}
val.then(copyStat, copyStat)
return
}
this._value = val
this._status = which
for (let i = this._handerAtPending.length; i > 0; i--) {
this._handerAtPending.shift()()
}
}
then(onSucc, onFail = it => { throw it }) {
return new MyPromise((res, rej) => {
let runHandler = () => {
let succOrFail = this._status === 'resolved' ? onSucc : onFail
MyPromise._nextTick(() => {
try {
let thenReturn = succOrFail(this._value)
res(thenReturn) // then返回的新promise的resolve
} catch (e) {
rej(e)
}
})
}
if (this._status !== 'pending') {
runHandler()
} else {
this._handerAtPending.push(runHandler)
}
})
}
static resolve(val) {
return val instanceof MyPromise ? val : new MyPromise(res => res(val))
}
static reject(val) {
return new MyPromise((res, rej) => rej(val))
}
static all(pomsAry) {
return new MyPromise((res, rej) => {
let resolveVals = []
let resolvedCount = 0
let len = pomsAry.length
for (let [i, poms] of pomsAry.entries()) {
MyPromise.resolve(poms).then((val) => {
resolvedCount += 1
resolveVals[i] = val
if (resolvedCount === len) {
res(resolveVals)
}
}, rej)
}
})
}
static race(pomsAry) {
return new MyPromise((res, rej) => {
for (let poms of pomsAry) {
MyPromise.resolve(poms).then(res, rej)
}
})
}
static _nextTick(fn) {
if (typeof process === 'object' && process.nextTick) {
process.nextTick(fn)
} else if (MutationObserver && document && document.createTextNode) {
let observer = new MutationObserver(fn)
let textNode = document.createTextNode('-')
observer.observe(textNode, {
characterData: true
})
textNode.data = ''
} else {
setTimeout(fn)
}
}
}
// 导出以方便测试
if (module) {
module.exports = MyPromise
}