手写完整版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;

浙公网安备 33010602011771号