1 // ES6 ES2015
2 // https://promisesaplus.com
3
4 const PROMISE_STATUS_PENDING = 'pending'
5 const PROMISE_STATUS_FULFILLED = 'fulfilled'
6 const PROMISE_STATUS_REJECTED = 'reject'
7
8 // 工具函数
9 function execFunctionWithCatchError(execFn, value, resolve, reject){
10 try {
11 const result = execFn(value)
12 resolve(result)
13 } catch (err) {
14 reject(err)
15 }
16 }
17
18 class HYPromise{
19 constructor(executor) {
20 this.status = PROMISE_STATUS_PENDING
21 this.value = undefined
22 this.reason = undefined
23 this.onFulfilledFns = []
24 this.onRejectedFns = []
25
26 const resolve = (value) => {
27 if (this.status === PROMISE_STATUS_PENDING){
28 // setTimeout(() => {
29 // this.value = value
30 // this.onFulfilled(this.value)
31 // }, 0);
32 // 添加微任务
33 queueMicrotask(() => { //加入微任务
34 if (this.status !== PROMISE_STATUS_PENDING) return
35 this.status = PROMISE_STATUS_FULFILLED
36 this.value = value
37 this.onFulfilledFns.forEach(fn=>{
38 fn(this.value)
39 })
40 });
41 }
42 }
43
44 const reject = (reason) => {
45 if (this.status === PROMISE_STATUS_PENDING){
46 queueMicrotask(()=>{
47 if (this.status !== PROMISE_STATUS_PENDING) return
48 this.status = PROMISE_STATUS_REJECTED
49 this.reason = reason
50 this.onRejectedFns.forEach(fn=>{
51 fn(this.reason)
52 })
53 })
54 }
55 }
56
57 try {
58 executor(resolve,reject)
59 } catch (err){
60 reject(err)
61 }
62 }
63
64 then(onFulfilled, onRejected) {
65 const defaultOnRejected = err => {throw err }
66 onRejected = onRejected || defaultOnRejected
67
68 const defaultOnFulfilled = value => { return value}
69 onFulfilled = onFulfilled || defaultOnFulfilled
70
71 return new HYPromise((resolve,reject) => {
72 // 1.如果在then 调用的时候,状态已经确定下来
73 if (this.status === PROMISE_STATUS_FULFILLED && onFulfilled){
74 execFunctionWithCatchError(onFulfilled, this.value, resolve, reject)
75 }
76 if (this.status === PROMISE_STATUS_REJECTED && onRejected){
77 execFunctionWithCatchError(onRejected, this.reason, resolve, reject)
78 }
79
80 //onFulfilled, onRejected可以做一些判断 传空传其他
81 // 2.将成功回调和失败的回调放到数组中
82 if (this.status === PROMISE_STATUS_PENDING){
83 if (onFulfilled) this.onFulfilledFns.push(() => {
84 execFunctionWithCatchError(onFulfilled, this.value, resolve, reject)
85 })
86 if (onRejected) this.onRejectedFns.push(() => {
87 execFunctionWithCatchError(onRejected, this.reason, resolve, reject)
88 })
89 }
90 })
91 }
92
93 catch(onRejected){
94 return this.then(undefined, onRejected)
95 }
96
97 finally(onFinally){
98 this.then(() => {
99 onFinally()
100 }, () => {
101 onFinally()
102 })
103 }
104
105 static resolve(value) {
106 return new HYPromise((resolve) => resolve(value))
107 }
108
109 static reject(reason){
110 return new HYPromise((resolve, reject) => reject(reason))
111 }
112
113 static all(promises) {
114 return new HYPromise((resolve, reject) => {
115 const values = []
116 promises.forEach(promise => {
117 promise.then(res => {
118 values.push(res)
119 if(values.length === promise.length){
120 resolve(values)
121 }
122 }, err => {
123 reject(err)
124 })
125 })
126 })
127 }
128
129 static allSettled(promises) {
130 return new HYPromise((resolve) => {
131 const results = []
132 promises.forEach(promise => {
133 promise.then(res => {
134 results.push({ status: PROMISE_STATUS_FULFILLED, value: res})
135 if(results.length === promise.length){
136 resolve(results)
137 }
138 }, err => {
139 results.push({ status: PROMISE_STATUS_REJECTED, value: err})
140 if(results.length === promise.length){
141 resolve(results)
142 }
143 })
144 })
145 })
146 }
147
148 static race(promises) {
149 return new HYPromise((resolve, reject) => {
150 promises.forEach(promise => {
151 // promise.then(res => {
152 // resolve(res)
153 // }, err => {
154 // reject(err)
155 // })
156 promise.then(resolve,reject)
157 })
158 })
159 }
160
161 static any(promises) {
162 // resolve必须等到有一个成功的结果
163 // reject所有的都失败才执行reject
164 const reasons = []
165 return new HYPromise((resolve, reject) => {
166 promises.forEach(promise => {
167 promise.then(resolve, err => {
168 reasons.push(err)
169 if (reasons.length === promises.length){
170 reject(new AggregateError(reasons))
171 }
172 })
173 })
174 })
175 }
176 }
177
178 HYPromise.resolve('hello').then(res => {
179 console.log('res:',res)
180 })
181
182 // const promise = new HYPromise((resolve,reject) => {
183 // console.log('状态pending')
184 // resolve(2222)
185 // reject(1111)
186 // })
187
188 // promise.then(res=>{
189 // console.log('res1:',res)
190 // }).catch(err=>{
191 // console.log('err1:',err)
192 // })
193
194 // promise.then(res=>{
195 // console.log('res2:',res)
196 // },err=>{
197 // console.log('err2:',err)
198 // })
199
200 // setTimeout(() => {
201 // promise.then(res=>{
202 // console.log('res3:',res)
203 // },err=>{
204 // console.log('err3:',err)
205 // })
206 // }, 1000);