promise 简单实现
2018-08-20 22:57 罗小二 阅读(334) 评论(0) 收藏 举报参考 Promise A+ 简单实现 promise,用的setTimeout 模拟的异步,与实际浏览器Promise 有出入(具体可以看Event loop 相关),本文只做思路理解参考。
Promise 的简单实现,主要理解规范,也可以再理解一下几个点方变记忆:
- Promise的三种状态(pending,fulfilled,rejected), pending状态转移后不可变
- resolve , resolve a promise with a promise
- reject
- Promise.prototype.then 返回一个新的promise 对象(链式操作)
- thenable对象
1.简单实现
1 const PENDING = 'pending' 2 const FULFILLED = 'fulfilled' 3 const REJECTED = 'rejected' 4 5 function needResolve() { 6 throw new TypeError('need pass function to Promise') 7 } 8 9 function needuseNew() { 10 throw new TypeError( 11 'Promise is a constructor and should be called with the `new` keyword' 12 ) 13 } 14 15 function Promise(task) { 16 var self = this 17 this.state = PENDING 18 this.value 19 this.fulArr = [] 20 this.rejArr = [] 21 22 function resolve(value) { 23 if (value != null && value.then && typeof value.then == 'function') { 24 return value.then(resolve, reject) 25 } 26 setTimeout(() => { 27 if (self.state == PENDING) { 28 self.state = FULFILLED 29 self.value = value 30 self.fulArr.forEach(item => { 31 item(self.value) 32 }) 33 } 34 }) 35 } 36 37 function reject(reason) { 38 setTimeout(() => { 39 if (self.state == PENDING) { 40 self.state = REJECTED 41 self.value = reason 42 self.fulArr.forEach(item => { 43 item(self.value) 44 }) 45 } 46 }) 47 } 48 typeof task !== 'function' && needResolve() 49 !(this instanceof Promise) && needResolve() 50 try { 51 task( 52 function(value) { 53 resolve(value) 54 }, 55 function(reason) { 56 reject(reason) 57 } 58 ) 59 } catch (e) { 60 reject(e) 61 } 62 } 63 64 function resolvePromise(promise, x, resolve, reject) { 65 if (promise === x) { 66 return reject(new TypeError('do not resolve promise with itself')) 67 } 68 var then, called 69 // resolve promise with promise 70 if (x instanceof Promise) { 71 if (x.status == PENDING) { 72 x.then(function(y) { 73 resolvePromise(promise, y, resolve, reject) 74 }, reject) 75 } else { 76 x.then(resolve, reject) 77 } 78 // thenable 其它的then 79 } else if (x !== null && (typeof x == 'function' || typeof x == 'object')) { 80 try { 81 // resolve promise with promise 82 then = x.then 83 if (typeof then === 'function') { 84 then.call( 85 x, 86 function(y) { 87 if (called) { 88 return 89 } 90 called = true 91 resolvePromise(promise, y, resolve, reject) 92 }, 93 function(r) { 94 if (called) { 95 return 96 } 97 called = true 98 reject(r) 99 } 100 ) 101 } else { 102 resolve(x) 103 } 104 } catch (e) { 105 if (called) { 106 return 107 } 108 called = true 109 reject(e) 110 } 111 } else { 112 resolve(x) 113 } 114 } 115 Promise.prototype.then = function(onFulfilled, onRejected) { 116 var self = this 117 onFulfilled = 118 typeof onFulfilled === 'function' 119 ? onFulfilled 120 : function(value) { 121 return value 122 } 123 onRejected = 124 typeof onRejected === 'function' 125 ? onRejected 126 : function(reason) { 127 throw reason 128 } 129 var promise2 130 if (self.state == PENDING) { 131 promise2 = new Promise(function(resolve, reject) { 132 self.fulArr.push(value => { 133 try { 134 let x = onFulfilled(value) 135 resolvePromise(promise2, x, resolve, reject) 136 } catch (e) { 137 reject(e) 138 } 139 }) 140 self.reject.push(reason => { 141 try { 142 let x = onRejected(reason) 143 resolvePromise(promise2, x, resolve, reject) 144 } catch (e) { 145 reject(e) 146 } 147 }) 148 }) 149 } 150 if (self.state == FULFILLED) { 151 promise2 = new Promise(function(resolve, reject) { 152 setTimeout(() => { 153 try { 154 let x = onFulfilled(self.value) 155 resolvePromise(promise2, x, resolve, reject) 156 } catch (e) { 157 reject(e) 158 } 159 }) 160 }) 161 } 162 if (self.state == REJECTED) { 163 promise2 = new Promise(function(resolve, reject) { 164 setTimeout(() => { 165 try { 166 let x = onRejected(self.value) 167 resolvePromise(promise2, x, resolve, reject) 168 } catch (e) { 169 reject(e) 170 } 171 }) 172 }) 173 } 174 // then 必须返回一个新的promise 175 return promise2 176 } 177 178 Promise.prototype.catch = function(onRejected) { 179 return this.then(null, onRejected) 180 } 181 182 Promise.resolve = function(value) { 183 return new Promise((resolve, reject) => { 184 resolve(value) 185 }) 186 } 187 Promise.reject = function(value) { 188 return new Promise((resolve, reject) => { 189 reject(value) 190 }) 191 } 192 193 function gen(time, resolve) { 194 let result = [] 195 let i = 0 196 return function(index, value) { 197 if (i < time) { 198 i++ 199 result[index] = value 200 } else { 201 resolve(result) 202 } 203 } 204 } 205 206 Promise.race = function(arr) { 207 return new Promise((resolve, reject) => { 208 for (let i = 0; i < arr.length; i++) { 209 Promise.resolve(arr[i]).then(resolve, reject) 210 } 211 }) 212 } 213 Promise.all = function(arr) { 214 return new Promise((resolve, reject) => { 215 let done = gen(arr.length, resolve) 216 for (let i = 0; i < arr.length; i++) { 217 Promise.resolve(arr[i]).then(function(value) { 218 done(value, i) 219 }, reject) 220 } 221 }) 222 } 223 module.exports = Promise
浙公网安备 33010602011771号