-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path重拾pro.js
139 lines (129 loc) · 3.6 KB
/
重拾pro.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
const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";
// const isArray = (obj) => Object.prototype.toString.call(obj).slice(8, -1).toLocaleLowerCase() === 'array'
const isIterable = obj => obj != null && typeof obj[Symbol.iterator] === 'function';
function MyPromise(fn) {
if (typeof fn !== 'function') {
throw new Error('promise 必须接受一个函数作为参数')
}
let self = this
self.value = undefined
self.status = PENDING
self.onRejectedCbs = []
self.onFulfilledCbs = []
function resolve(value) {
if (self.status !== PENDING) return
self.status = FULFILLED
self.value = value
if (self.onFulfilledCbs.length > 0) {
setTimeout(() => {
self.onFulfilledCbs.forEach(fn => fn())
}, 0);
}
}
function reject(reason) {
if (self.status !== PENDING) return
self.status = REJECTED
self.value = reason
if (self.onRejectedCbs.length > 0) {
setTimeout(() => {
self.onRejectedCbs.forEach(fn => fn())
}, 0);
}
}
try {
fn(resolve, reject)
} catch (error) {
reject(error)
}
}
MyPromise.prototype.then = function (onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value
onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }
const self = this
return new MyPromise((resolve, reject) => {
const handlePromise = (callback) => {
try {
const res = callback(self.value)
if (res instanceof MyPromise) {
res.then(resolve, reject)
} else {
resolve(res)
}
} catch (error) {
reject(error)
}
}
if (self.status === PENDING) {
self.onFulfilledCbs.push(() => { handlePromise(onFulfilled) })
self.onRejectedCbs.push(() => { handlePromise(onRejected) })
} else if (self.status === FULFILLED) {
handlePromise(onFulfilled)
} else {
handlePromise(onRejected)
}
})
}
MyPromise.prototype.catch = function (onRejected) {
return this.then(undefined, onRejected)
}
MyPromise.resolve = function (value) {
return new MyPromise((resolve, reject) => {
if (value instanceof MyPromise) {
value.then(resolve, reject)
} else {
resolve(value)
}
})
}
MyPromise.reject = function (reason) {
return new MyPromise((resolve, reject) => {
reject(reason)
})
}
MyPromise.all = function (promises) {
if (!isIterable(promises)) throw new TypeError('请传入一个可以迭代的对象')
const length = promises.length
let resIndex = 0, res = []
return new MyPromise((resolve, reject) => {
promises.forEach((p, index) => {
MyPromise.resolve(p).then(value => {
resIndex++
res[index] = value
if (resIndex === length) {
resolve(res)
}
}).catch(err => reject(err))
})
})
}
MyPromise.race = function (promises) {
if (!isIterable(promises)) throw new TypeError('请传入一个可以迭代的对象')
return new MyPromise((resolve, reject) => {
promises.forEach(p => {
Promise.resolve(p).then(value => {
resolve(value)
}, reason => {
reject(reason)
})
})
})
}
// let promise = new MyPromise((resolve, reject) => {
// setTimeout(() => {
// resolve('cccc')
// }, 1000);
// })
// promise.then((value) => {
// console.log(value)
// throw '111das'
// }).then(1,2).then(res => console.log(res), err => console.log(err))
// MyPromise.all([1, promise, 2]).then(res => {
// console.log(res)
// })
const promise = MyPromise.resolve()
.then(() => {
return promise
})
promise.catch(console.error)