手写完整版promise 并且测试通过

 

完整代码:https://github.com/waihoyu/promise

参考规范:https://www.ituring.com.cn/article/66566

 

  1 /*
  2  *@description:  promise 的手动实现 
  3  *@author: Wai HoYu
  4  *@date: 2019-12-01 01:41:13
  5  *@version: V1.0.5
  6  *@comments: 测试promise完整性插件:npm i promises-aplus-tests
  7  *@comments: 命令行测试程序: npx promises-aplus-tests promise.js
  8  */
  9 
 10 class Promise {
 11 
 12     constructor(executor) {
 13         //不能相信用户的输入,一定要进行参数校验
 14         if (typeof executor !== 'function') {
 15             throw new TypeError(` Promise resolver ${executor} is not a function `);
 16         }
 17         this.initValue();
 18         this.initBind();
 19         try {
 20             executor(this.resolve, this.reject);
 21         } catch (error) {
 22             this.reject(error);
 23         }
 24     }
 25 
 26     initBind() {
 27         this.resolve = this.resolve.bind(this);
 28         this.reject = this.reject.bind(this);
 29     }
 30 
 31     initValue() {
 32         this.value = null;
 33         this.reason = null;
 34         this.state = Promise.PENDING;
 35         this.onFullfilledCallbacks = [];
 36         this.onRejectedCallbacks = [];
 37     }
 38 
 39     resolve(value) {
 40         //成功后的一系列操作 状态的改变  成功回调的执行
 41         if (this.state === Promise.PENDING) {
 42             this.state = Promise.FULLFILLED;
 43             this.value = value;
 44             this.onFullfilledCallbacks.forEach((fn) => {
 45                 fn(this.value);
 46             });
 47         }
 48     }
 49 
 50     reject(reason) {
 51         if (this.state === Promise.PENDING) {
 52             this.state = Promise.REJECTED;
 53             this.reason = reason;
 54             this.onRejectedCallbacks.forEach((fn) => {
 55                 fn(this.reason);
 56             });
 57         }
 58     }
 59 
 60     then(onFullfilled, onRejected) {
 61         if (typeof onFullfilled !== 'function') {
 62             onFullfilled = function (value) {
 63                 return value;
 64             }
 65         }
 66 
 67         if (typeof onRejected !== 'function') {
 68             onRejected = function (reason) {
 69                 throw reason;
 70             }
 71         }
 72 
 73         let promise2 = new Promise((resolve, reject) => {
 74 
 75             if (this.state === Promise.FULLFILLED) {
 76                 setTimeout(() => {
 77                     try {
 78                         const x = onFullfilled(this.value);
 79                         Promise.resolvePromise(promise2, x, resolve, reject)
 80                     } catch (error) {
 81                         reject(error);
 82                     }
 83                 });
 84             }
 85 
 86             if (this.state === Promise.REJECTED) {
 87                 setTimeout(() => {
 88                     try {
 89                         const x = onRejected(this.reason);
 90                         Promise.resolvePromise(promise2, x, resolve, reject)
 91                     } catch (error) {
 92                         reject(error);
 93                     }
 94                 });
 95             }
 96 
 97             if (this.state === Promise.PENDING) {
 98                 this.onFullfilledCallbacks.push(value => {
 99                     setTimeout(() => {
100                         try {
101                             const x = onFullfilled(value);
102                             Promise.resolvePromise(promise2, x, resolve, reject)
103                         } catch (error) {
104                             reject(error)
105                         }
106                     })
107                 });
108 
109                 this.onRejectedCallbacks.push(reason => {
110                     setTimeout(() => {
111                         try {
112                             const x = onRejected(reason);
113                             Promise.resolvePromise(promise2, x, resolve, reject)
114                         } catch (error) {
115                             reject(error);
116                         }
117                     })
118                 });
119             }
120         });
121         return promise2;
122     }
123 }
124 
125 Promise.PENDING = 'pending';
126 Promise.FULLFILLED = 'fullfilled';
127 Promise.REJECTED = 'rejected';
128 
129 Promise.resolvePromise = function (promise2, x, resolve, reject) {
130     if (promise2 === x) {
131         reject(new TypeError('Chaining cycle detected for promise'));
132     }
133     let called = false;
134     if (x instanceof Promise) {
135         x.then(
136             value => {
137                 Promise.resolvePromise(promise2, value, resolve, reject);
138             },
139             reason => {
140                 reject(reason);
141             });
142     }
143     // 
144     else if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
145         try {
146             const then = x.then;
147             if (typeof then === 'function') {
148                 then.call(
149                     x,
150                     value => {
151                         if (called) return
152                         called = true
153                         Promise.resolvePromise(promise2, value, resolve, reject);
154                     }, reason => {
155                         if (called) return
156                         called = true
157                         reject(reason);
158                     });
159             } else {
160                 if (called) return
161                 called = true
162                 resolve(x);
163             }
164         } catch (error) {
165             if (called) return
166             called = true
167             reject(error)
168         }
169     }
170     // 
171     else {
172         resolve(x);
173     }
174 }
175 
176 Promise.defer = Promise.deferred = function () {
177     let dfd = {}
178     dfd.promise = new Promise((resolve, reject) => {
179         dfd.resolve = resolve
180         dfd.reject = reject
181     })
182     return dfd
183 }
184 
185 module.exports = Promise;

 

 

 

 

  

posted @ 2019-12-01 20:57  WaiHoYu  阅读(530)  评论(0)    收藏  举报