1 // ES6 ES2015 2 // https://promisesaplus.com 3 4 const PROMISE_STATUS_PENDING = 'pending' 5 const PROMISE_STATUS_FULFILLED = 'fulfilled' 6 const PROMISE_STATUS_REJECTED = 'reject' 7 8 // 工具函数 9 function execFunctionWithCatchError(execFn, value, resolve, reject){ 10 try { 11 const result = execFn(value) 12 resolve(result) 13 } catch (err) { 14 reject(err) 15 } 16 } 17 18 class HYPromise{ 19 constructor(executor) { 20 this.status = PROMISE_STATUS_PENDING 21 this.value = undefined 22 this.reason = undefined 23 this.onFulfilledFns = [] 24 this.onRejectedFns = [] 25 26 const resolve = (value) => { 27 if (this.status === PROMISE_STATUS_PENDING){ 28 // setTimeout(() => { 29 // this.value = value 30 // this.onFulfilled(this.value) 31 // }, 0); 32 // 添加微任务 33 queueMicrotask(() => { //加入微任务 34 if (this.status !== PROMISE_STATUS_PENDING) return 35 this.status = PROMISE_STATUS_FULFILLED 36 this.value = value 37 this.onFulfilledFns.forEach(fn=>{ 38 fn(this.value) 39 }) 40 }); 41 } 42 } 43 44 const reject = (reason) => { 45 if (this.status === PROMISE_STATUS_PENDING){ 46 queueMicrotask(()=>{ 47 if (this.status !== PROMISE_STATUS_PENDING) return 48 this.status = PROMISE_STATUS_REJECTED 49 this.reason = reason 50 this.onRejectedFns.forEach(fn=>{ 51 fn(this.reason) 52 }) 53 }) 54 } 55 } 56 57 try { 58 executor(resolve,reject) 59 } catch (err){ 60 reject(err) 61 } 62 } 63 64 then(onFulfilled, onRejected) { 65 const defaultOnRejected = err => {throw err } 66 onRejected = onRejected || defaultOnRejected 67 68 const defaultOnFulfilled = value => { return value} 69 onFulfilled = onFulfilled || defaultOnFulfilled 70 71 return new HYPromise((resolve,reject) => { 72 // 1.如果在then 调用的时候,状态已经确定下来 73 if (this.status === PROMISE_STATUS_FULFILLED && onFulfilled){ 74 execFunctionWithCatchError(onFulfilled, this.value, resolve, reject) 75 } 76 if (this.status === PROMISE_STATUS_REJECTED && onRejected){ 77 execFunctionWithCatchError(onRejected, this.reason, resolve, reject) 78 } 79 80 //onFulfilled, onRejected可以做一些判断 传空传其他 81 // 2.将成功回调和失败的回调放到数组中 82 if (this.status === PROMISE_STATUS_PENDING){ 83 if (onFulfilled) this.onFulfilledFns.push(() => { 84 execFunctionWithCatchError(onFulfilled, this.value, resolve, reject) 85 }) 86 if (onRejected) this.onRejectedFns.push(() => { 87 execFunctionWithCatchError(onRejected, this.reason, resolve, reject) 88 }) 89 } 90 }) 91 } 92 93 catch(onRejected){ 94 return this.then(undefined, onRejected) 95 } 96 97 finally(onFinally){ 98 this.then(() => { 99 onFinally() 100 }, () => { 101 onFinally() 102 }) 103 } 104 105 static resolve(value) { 106 return new HYPromise((resolve) => resolve(value)) 107 } 108 109 static reject(reason){ 110 return new HYPromise((resolve, reject) => reject(reason)) 111 } 112 113 static all(promises) { 114 return new HYPromise((resolve, reject) => { 115 const values = [] 116 promises.forEach(promise => { 117 promise.then(res => { 118 values.push(res) 119 if(values.length === promise.length){ 120 resolve(values) 121 } 122 }, err => { 123 reject(err) 124 }) 125 }) 126 }) 127 } 128 129 static allSettled(promises) { 130 return new HYPromise((resolve) => { 131 const results = [] 132 promises.forEach(promise => { 133 promise.then(res => { 134 results.push({ status: PROMISE_STATUS_FULFILLED, value: res}) 135 if(results.length === promise.length){ 136 resolve(results) 137 } 138 }, err => { 139 results.push({ status: PROMISE_STATUS_REJECTED, value: err}) 140 if(results.length === promise.length){ 141 resolve(results) 142 } 143 }) 144 }) 145 }) 146 } 147 148 static race(promises) { 149 return new HYPromise((resolve, reject) => { 150 promises.forEach(promise => { 151 // promise.then(res => { 152 // resolve(res) 153 // }, err => { 154 // reject(err) 155 // }) 156 promise.then(resolve,reject) 157 }) 158 }) 159 } 160 161 static any(promises) { 162 // resolve必须等到有一个成功的结果 163 // reject所有的都失败才执行reject 164 const reasons = [] 165 return new HYPromise((resolve, reject) => { 166 promises.forEach(promise => { 167 promise.then(resolve, err => { 168 reasons.push(err) 169 if (reasons.length === promises.length){ 170 reject(new AggregateError(reasons)) 171 } 172 }) 173 }) 174 }) 175 } 176 } 177 178 HYPromise.resolve('hello').then(res => { 179 console.log('res:',res) 180 }) 181 182 // const promise = new HYPromise((resolve,reject) => { 183 // console.log('状态pending') 184 // resolve(2222) 185 // reject(1111) 186 // }) 187 188 // promise.then(res=>{ 189 // console.log('res1:',res) 190 // }).catch(err=>{ 191 // console.log('err1:',err) 192 // }) 193 194 // promise.then(res=>{ 195 // console.log('res2:',res) 196 // },err=>{ 197 // console.log('err2:',err) 198 // }) 199 200 // setTimeout(() => { 201 // promise.then(res=>{ 202 // console.log('res3:',res) 203 // },err=>{ 204 // console.log('err3:',err) 205 // }) 206 // }, 1000);