1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
| const stateMap = { PENDING: 'pending', FULFILLED: 'fulfilled', REJECTED: 'rejected', }
class MyPromise { constructor(executor) { this.id = id; this.state = stateMap.PENDING; this.value = undefined; this.reason = undefined; this.fulfillCallbackList = []; this.rejectCallbackList = [];
const resolve = (value) => { if (this.state !== stateMap.PENDING) return; this.state = stateMap.FULFILLED; this.value = value; this.fulfillCallbackList.forEach((callback) => callback(this.value)); } const reject = (reason) => { if (this.state !== stateMap.PENDING) return; this.state = stateMap.REJECTED; this.reason = reason; this.rejectCallbackList.forEach((callback) => callback(this.reason)); }
try { executor(resolve, reject); } catch (error) { reject(error); } }
then(onFulFill, onReject) { const thenPromise = new MyPromise((resolve, reject) => { if (this.state === stateMap.FULFILLED) { try { const value = onFulFill(this.value); resolve(value); } catch (error) { reject(error); } } else if (this.state === stateMap.REJECTED) { try { const reason = onReject(this.reason); reject(reason); } catch (error) { reject(error); } } else { this.fulfillCallbackList.push(() => { try { const value = onFulFill(this.value); resolve(value); } catch (error) { reject(error); } });
this.rejectCallbackList.push(() => { try { const reason = onReject(this.reason); resolve(reason); } catch (error) { reject(error); } }) } });
return thenPromise; }
catch(rejectCallback) { return this.then(null, rejectCallback); } }
function test(PromiseType = Promise) { const promise = new PromiseType((resolve, reject) => { setTimeout(() => { const num = Math.random() * 10; if (num < 5) { resolve(num); } else { reject('num is not less than 5'); } }, 3000); }); promise.then((value) => { console.log('fulfill-1', value); value = `then1-${value}`; },(reason) => { console.log('reject-1', reason); reason = `then1-${reason}`; return reason; }).then((value)=> { console.log('fulfill-2', value); value = `then2-${value}`; }, (reason) => { console.log('reject-2', reason); reason = `then2-${reason}`; }).then((value) => { console.log('promise', promise, value); }); }
test(Promise);
test(MyPromise);
|