手动实现 Promise
实现:
1 ((root, factory) => { 2 if (typeof exports === "object") { 3 module.exports = factory(); 4 } else { 5 root.MyPromise = factory(); 6 } 7 })(this, function () { 8 const PENDING = "pending", 9 FULFILLED = "fulfilled", 10 REJECTED = "rejected"; 11 12 return class MyPromise { 13 status = PENDING; 14 data = null; 15 onResolvedCache = null; 16 onRejectedCache = null; 17 constructor(executor) { 18 const [resolve, reject] = [ 19 (value) => { 20 if (this.status === PENDING) { 21 this.data = value; 22 this.status = FULFILLED; 23 this.onResolvedCache && this.onResolvedCache(); 24 } 25 }, 26 (reason) => { 27 if (this.status === PENDING) { 28 this.data = reason; 29 this.status = REJECTED; 30 this.onRejectedCache && this.onRejectedCache(); 31 } 32 }, 33 ]; 34 35 try { 36 executor(resolve, reject); 37 } catch (err) { 38 reject(err); 39 } 40 } 41 42 then(onResolved, onRejected) { 43 return new MyPromise((resolve, reject) => { 44 const handle = (callback) => { 45 let result = null; 46 if (callback instanceof Function) { 47 result = callback(this.data); 48 } 49 50 if (result instanceof MyPromise) { 51 result.then(resolve, reject); 52 } else { 53 this.status === FULFILLED 54 ? resolve(this.data) 55 : reject(this.data); 56 } 57 }; 58 59 switch (this.status) { 60 case PENDING: 61 this.onResolvedCache = () => handle(onResolved); 62 this.onRejectedCache = () => handle(onRejected); 63 break; 64 case FULFILLED: 65 handle(onResolved); 66 break; 67 case REJECTED: 68 handle(onRejected); 69 break; 70 } 71 }); 72 } 73 74 catch(onRejected) { 75 return this.then(null, onRejected); 76 } 77 78 static resolve(data) { 79 return new MyPromise((resolve, reject) => { 80 if (data instanceof MyPromise) { 81 data.then(resolve, reject); 82 } else { 83 resolve(data); 84 } 85 }); 86 } 87 88 static reject(reason) { 89 return new MyPromise((resolve, reject) => { 90 if (reason instanceof MyPromise) { 91 reason.then(resolve, reject); 92 } else { 93 reject(reason); 94 } 95 }); 96 } 97 98 static all(promises) { 99 return new MyPromise((resolve, reject) => { 100 let values = []; 101 let resolvedCount = 0; 102 const promiseTotal = promises.length; 103 promises.forEach((promise) => { 104 promise.then( 105 (res) => { 106 values.push(res); 107 resolvedCount++; 108 if (resolvedCount === promiseTotal) { 109 resolve(values); 110 } 111 }, 112 (err) => { 113 reject(err); 114 }, 115 ); 116 }); 117 }); 118 } 119 120 static race(promises) { 121 return new MyPromise((resolve, reject) => { 122 promises.forEach((promise) => { 123 promise.then( 124 (res) => { 125 resolve(res); 126 }, 127 (err) => { 128 reject(err); 129 }, 130 ); 131 }); 132 }); 133 } 134 }; 135 });