promise

  1 /*
  2 尽可能还原 Promise 中的每一个 API, 并通过注释的方式描述思路和原理.
  3 */
  4 
  5 
  6 // 定义三个状态
  7 const PENDING = "PENDING";
  8 const RESOLVED = "RESOLVED";
  9 const REJECTED = 'REJECTED';
 10 function resolvePromise(x, promise2, resolve, reject) {
 11   //判断x === promise, 抛出类型错误
 12   if (x === promise2) {
 13     console.log('======')
 14     return reject(new TypeError('类型错误'))
 15   }
 16   // 允许状态改变一次
 17   let called = false;
 18 
 19 
 20 
 21   try {
 22     //判断x是否包含then属性,thenable
 23     if (typeof x === 'object' && x !== null) {
 24       const then = x.then;
 25       if (typeof then === "function") {
 26         // console.log(typeof then)
 27         then.call(x, v => {
 28           if (called) return;
 29           called = true;
 30           resolvePromise(v, promise2, resolve, reject)
 31         }, r => {
 32           if (called) return;
 33           called = true;
 34           reject(r)
 35         })
 36       } else {
 37         if (called) return;
 38         called = true;
 39         resolve(x)
 40       }
 41     } else {
 42       if (called) return;
 43       called = true;
 44       resolve(x)
 45     }
 46   } catch (e) {
 47     if (called) return;
 48     called = true;
 49     reject(e)
 50   }
 51 }
 52 class Promise {
 53   constructor(exectuor) {
 54     try {
 55       //捕获执行器错误
 56       exectuor(this.resolve, this.reject)
 57     } catch (e) {
 58       this.reject(e)
 59     }
 60   }
 61 
 62   status = PENDING;
 63   value = null;
 64   reason = null;
 65   //存储失败和成功的回调
 66   onFullFilledCallbacks = [];
 67   onRejectedCallbacks = [];
 68 
 69   static all (args) {
 70     return new Promise((resolve, reject) => {
 71       args.reduce((prev, curr, i, arr) => {
 72         if (curr instanceof Promise) {
 73           curr.then((v) => {
 74             prev[i] = v;
 75             if (prev.length === arr.length) {
 76               resolve(prev)
 77             }
 78           }, r=> {
 79             reject(r)
 80           })
 81         } else {
 82           prev[i] = curr;
 83         }
 84         return prev;
 85       }, [])
 86     })
 87   }
 88   static resolve (v) {
 89     if (v instanceof  Promise) return v;
 90     return new Promise((resolve ,reject) => resolve(v));
 91   }
 92   static reject(r) {
 93     return new Promise((resolve,reject)=>{
 94       reject(r)
 95     })
 96   }
 97   static allSettled (args) {
 98     return new Promise((resolve, reject) => {
 99       function addData(prev, index, value){
100         prev[index] = value;
101         if (prev.length === args.length) {
102           resolve(prev)
103         }
104       }
105       args.reduce((prev, curr, index, arr) => {
106         if (curr instanceof Promise) {
107           curr.then(res => {
108             addData(prev, index, {
109               value: res,
110               status: 'fulfilled'
111             })
112           }, r => {
113             addData(prev, index, {
114               reason: r,
115               status: 'rejected'
116             })
117           })
118         } else {
119           addData(prev, index, {
120             reason: curr,
121             status: 'fulfilled'
122           })
123         }
124       })
125     })
126   }
127 
128   static race(args) {
129     return new Promise((resolve, reject) => {
130       args.forEach((item) => {
131         if (item instanceof Promise) {
132           item.then(v => {
133             resolve(v)
134           }, r => {
135             reject(r)
136           })
137         } else {
138           resolve(item)
139         }
140       })
141     })
142   }
143 
144   finally (cb) {
145     return this.then(v => {
146       return Promise.resolve(cb()).then(() => v);
147     }, r => {
148       return Promise.resolve(cb()).then(() => { throw r })
149     })
150   }
151 
152   resolve = (v) => {
153 
154     //只有状态为pending才执行
155     if (this.status === PENDING) {
156       this.status = RESOLVED;
157       this.value = v;
158       this.onFullFilledCallbacks.forEach(c => c())
159     }
160   }
161 
162   reject = (r) => {
163     if (this.status === PENDING) {
164       this.status = REJECTED;
165       this.reason = r;
166       this.onRejectedCallbacks.forEach(c => c())
167     }
168   }
169 
170   then(onFullFilled, onRejected) {
171     //onFullFilled onRejected类型判断
172     if (typeof onFullFilled !== 'function') onFullFilled = v => v;
173     if (typeof onFullFilled !== 'function') {
174       onRejected = r => {
175         throw r;
176       }
177     }
178     const promise2 = new Promise((resolve, reject) => {
179       if (this.status === RESOLVED) {
180         // Promise为微任务,所以放到微任务队列执行
181         queueMicrotask(() => {
182           try {
183             const x = onFullFilled(this.value);
184             resolvePromise(x, promise2, resolve, reject)
185           } catch (e) {
186             reject(e)
187           }
188         })
189       }
190 
191       if (this.status === REJECTED) {
192         queueMicrotask(() => {
193           try {
194             const x = onRejected(this.reason)
195             resolvePromise(x, promise2, resolve, reject)
196           } catch (e) {
197             reject(e)
198           }
199         })
200       }
201 
202       if (this.status === PENDING) {
203         //如果状态为pending,则执行方法放入数组中,等待resolve或reject时候执行
204         this.onFullFilledCallbacks.push(() => {
205           queueMicrotask(() => {
206             try {
207               const x = onFullFilled(this.value);
208               resolvePromise(x, promise2, resolve, reject)
209             } catch (e) {
210               reject(e)
211             }
212           })
213         })
214 
215         this.onRejectedCallbacks.push(() => {
216           queueMicrotask(() => {
217             try {
218               const x = onRejected(this.reason);
219               resolvePromise(x, promise2, resolve, reject)
220             } catch (e) {
221               reject(e)
222             }
223           })
224         })
225       }
226     })
227     return promise2;
228   }
229 }
230 
231 Promise.deferred = function() {
232   var result = {};
233   result.promise = new Promise(function(resolve, reject){
234     result.resolve = resolve;
235     result.reject = reject;
236   });
237 
238   return result;
239 }
240 
241 module.exports = Promise;

 

posted @ 2021-06-29 19:22  一个动态类型的幽灵  阅读(29)  评论(0编辑  收藏  举报