Shu-How Zの小窝

Loading...

手写Promise

  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);

 

posted @ 2023-09-17 19:51  KooTeam  阅读(9)  评论(0)    收藏  举报