ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

promise

2021-06-29 19:31:58  阅读:187  来源: 互联网

标签:resolve return promise reject Promise prev called


  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;

 

标签:resolve,return,promise,reject,Promise,prev,called
来源: https://www.cnblogs.com/ndh074512/p/14951622.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有