Javascript实现promise
Posted 时光游弋
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Javascript实现promise相关的知识,希望对你有一定的参考价值。
1 // 三种状态 2 const PENDING = "pending"; 3 const RESOLVED = "resolved"; 4 const REJECTED = "rejected"; 5 // promise 接收一个函数参数,该函数会立即执行 6 function MyPromise(fn) { 7 let _this = this; 8 _this.currentState = PENDING; 9 _this.value = undefined; 10 // 用于保存 then 中的回调,只有当 promise 11 // 状态为 pending 时才会缓存,并且每个实例至多缓存一个 12 _this.resolvedCallbacks = []; 13 _this.rejectedCallbacks = []; 14 15 _this.resolve = function (value) { 16 if (value instanceof MyPromise) { 17 // 如果 value 是个 Promise,递归执行 18 return value.then(_this.resolve, _this.reject) 19 } 20 setTimeout(() => { // 异步执行,保证执行顺序 21 if (_this.currentState === PENDING) { 22 _this.currentState = RESOLVED; 23 _this.value = value; 24 _this.resolvedCallbacks.forEach(cb => cb()); 25 } 26 }) 27 }; 28 29 _this.reject = function (reason) { 30 setTimeout(() => { // 异步执行,保证执行顺序 31 if (_this.currentState === PENDING) { 32 _this.currentState = REJECTED; 33 _this.value = reason; 34 _this.rejectedCallbacks.forEach(cb => cb()); 35 } 36 }) 37 } 38 // 用于解决以下问题 39 // new Promise(() => throw Error(‘error)) 40 try { 41 fn(_this.resolve, _this.reject); 42 } catch (e) { 43 _this.reject(e); 44 } 45 } 46 47 MyPromise.prototype.then = function (onResolved, onRejected) { 48 var self = this; 49 // 规范 2.2.7,then 必须返回一个新的 promise 50 var promise2; 51 // 规范 2.2.onResolved 和 onRejected 都为可选参数 52 // 如果类型不是函数需要忽略,同时也实现了透传 53 // Promise.resolve(4).then().then((value) => console.log(value)) 54 onResolved = typeof onResolved === ‘function‘ ? onResolved : v => v; 55 onRejected = typeof onRejected === ‘function‘ ? onRejected : r => throw r; 56 57 if (self.currentState === RESOLVED) { 58 return (promise2 = new MyPromise(function (resolve, reject) { 59 // 规范 2.2.4,保证 onFulfilled,onRjected 异步执行 60 // 所以用了 setTimeout 包裹下 61 setTimeout(function () { 62 try { 63 var x = onResolved(self.value); 64 resolutionProcedure(promise2, x, resolve, reject); 65 } catch (reason) { 66 reject(reason); 67 } 68 }); 69 })); 70 } 71 72 if (self.currentState === REJECTED) { 73 return (promise2 = new MyPromise(function (resolve, reject) { 74 setTimeout(function () { 75 // 异步执行onRejected 76 try { 77 var x = onRejected(self.value); 78 resolutionProcedure(promise2, x, resolve, reject); 79 } catch (reason) { 80 reject(reason); 81 } 82 }); 83 })); 84 } 85 86 if (self.currentState === PENDING) { 87 return (promise2 = new MyPromise(function (resolve, reject) { 88 self.resolvedCallbacks.push(function () { 89 // 考虑到可能会有报错,所以使用 try/catch 包裹 90 try { 91 var x = onResolved(self.value); 92 resolutionProcedure(promise2, x, resolve, reject); 93 } catch (r) { 94 reject(r); 95 } 96 }); 97 98 self.rejectedCallbacks.push(function () { 99 try { 100 var x = onRejected(self.value); 101 resolutionProcedure(promise2, x, resolve, reject); 102 } catch (r) { 103 reject(r); 104 } 105 }); 106 })); 107 } 108 }; 109 // 规范 2.3 110 function resolutionProcedure(promise2, x, resolve, reject) { 111 // 规范 2.3.1,x 不能和 promise2 相同,避免循环引用 112 if (promise2 === x) { 113 return reject(new TypeError("Error")); 114 } 115 // 规范 2.3.2 116 // 如果 x 为 Promise,状态为 pending 需要继续等待否则执行 117 if (x instanceof MyPromise) { 118 if (x.currentState === PENDING) { 119 x.then(function (value) { 120 // 再次调用该函数是为了确认 x resolve 的 121 // 参数是什么类型,如果是基本类型就再次 resolve 122 // 把值传给下个 then 123 resolutionProcedure(promise2, value, resolve, reject); 124 }, reject); 125 } else { 126 x.then(resolve, reject); 127 } 128 return; 129 } 130 // 规范 2.3.3.3.3 131 // reject 或者 resolve 其中一个执行过得话,忽略其他的 132 let called = false; 133 // 规范 2.3.3,判断 x 是否为对象或者函数 134 if (x !== null && (typeof x === "object" || typeof x === "function")) { 135 // 规范 2.3.3.2,如果不能取出 then,就 reject 136 try { 137 // 规范 2.3.3.1 138 let then = x.then; 139 // 如果 then 是函数,调用 x.then 140 if (typeof then === "function") { 141 // 规范 2.3.3.3 142 then.call( 143 x, 144 y => { 145 if (called) return; 146 called = true; 147 // 规范 2.3.3.3.1 148 resolutionProcedure(promise2, y, resolve, reject); 149 }, 150 e => { 151 if (called) return; 152 called = true; 153 reject(e); 154 } 155 ); 156 } else { 157 // 规范 2.3.3.4 158 resolve(x); 159 } 160 } catch (e) { 161 if (called) return; 162 called = true; 163 reject(e); 164 } 165 } else { 166 // 规范 2.3.4,x 为基本类型 167 resolve(x); 168 } 169 }
以上是关于Javascript实现promise的主要内容,如果未能解决你的问题,请参考以下文章