-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathpromise-5-reject.js
110 lines (101 loc) · 2.28 KB
/
promise-5-reject.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
/**
* Created by Capricorncd.
* https://github.com/capricorncd
* Date: 2020-06-07 16:01
*/
const PENDING = 'PENDING'
const FULFILLED = 'FULFILLED'
const REJECTED = 'REJECTED'
/**
* add reject logic
*/
class ZxPromise {
callbacks = []
// state
state = PENDING
// cache result
value = null
constructor (fn) {
fn(this._resolveHandler.bind(this), this._rejectHandler.bind(this))
}
then (onFulfilled, onRejected) {
return new ZxPromise((resolve, reject) => {
this._handle({
resolve,
onFulfilled,
reject,
onRejected
})
})
}
catch (onError) {
return this.then(null, onError)
}
_handle ({ onFulfilled, resolve, onRejected, reject }) {
if (this.state === PENDING) {
this.callbacks.push({ onFulfilled, resolve, onRejected, reject })
return
}
try {
if (this.state === FULFILLED) {
if (!onFulfilled) {
resolve(this.value)
return
}
// 把函数onFulfilled返回的结果,传递给下一个then
resolve(onFulfilled(this.value))
} else {
if (!onRejected) {
reject(this.value)
return
}
reject(onRejected(this.value))
}
} catch (err) {
reject(err)
}
}
_resolveHandler (value) {
// value 为ZxPromise
if (value instanceof ZxPromise) {
let then = value.then
if (typeof then === 'function') {
then.call(value, this._resolveHandler.bind(this))
return
}
}
// value 为普通值
this.state = FULFILLED
this.value = value
this.callbacks.forEach(fn => this._handle(fn))
}
_rejectHandler (err) {
this.state = REJECTED
this.value = err
this.callbacks.forEach(fn => this._handle(fn))
}
}
new ZxPromise((resolve, reject) => {
console.log('instance')
setTimeout(() => {
// resolve('world')
reject('test5 error')
}, 100)
}).then(res => {
console.log('then1', res)
return 'the text from then1 return'
}).then(res => {
console.log('then2', res)
return new ZxPromise(re => {
setTimeout(() => {
re('new ZxPromise instance')
}, 100)
})
}).then(res => {
console.log('then3', res)
return 'the text from then3 return'
}).then(res => {
console.log('then4', res)
}, err => {
console.error(err)
})