手写Promise及其方法
一、Promise-then
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 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 const PENDING = 'pending' const FULFILLED = 'fulfilled' const REJECTED = 'rejected' function resolvePromise (promise2, x, resolve, reject ) { if (promise2 === x) { return reject( new TypeError ("Chaining cycle detected for promise #<Promise>" ) ) } if ( (typeof x === 'object' && x !== null ) || typeof x === 'function' ) { let called = false try { let then = x.then if (typeof then === 'function' ) { then.call(x, y => { if (called) return called = true resolvePromise(promise2, y, resolve, reject) }, r => { if (called) return called = true reject(r) }) } else { resolve(x) } } catch (e) { if (called) return called = true reject(e) } } else { resolve(x) } } class Promise { constructor (executor ) { this .status = PENDING this .value = undefined this .reason = undefined this .onfulfilledCallback = [] this .onrejectedCallback = [] const resolve = (value ) => { if (this .status === PENDING) { this .status = FULFILLED this .value = value this .onfulfilledCallback.forEach(fn => fn()) } } const reject = (reason ) => { if (this .status === PENDING) { this .status = REJECTED this .reason = reason this .onrejectedCallback.forEach(fn => fn()) } } try { executor(resolve, reject) } catch (e) { reject(e) } } then (onfulfilled, onrejected) { onfulfilled = typeof onfulfilled === 'function' ? onfulfilled : value => value onrejected = typeof onrejected === 'function' ? onrejected : err => { throw err } const promise2 = new Promise ((resolve, reject ) => { if (this .status === FULFILLED) { setTimeout (() => { try { const x = onfulfilled(this .value) resolvePromise(promise2, x, resolve, reject) } catch (e) { reject(e) } }, 0 ) } if (this .status === REJECTED) { setTimeout (() => { try { const x = onrejected(this .reason) resolvePromise(promise2, x, resolve, reject) } catch (e) { reject(e) } }, 0 ) } if (this .status === PENDING) { this .onfulfilledCallback.push(() => { setTimeout (() => { try { const x = onfulfilled(this .value) resolvePromise(promise2, x, resolve, reject) } catch (e) { reject(e) } }, 0 ) }) this .onrejectedCallback.push(() => { setTimeout (() => { try { const x = onrejected(this .reason) resolvePromise(promise2, x, resolve, reject) } catch (e) { reject(e) } }, 0 ) }) } }) return promise2 } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 const isPromise = (value ) => { if ( (typeof value === 'object' && value !== null ) || typeof value === 'function' ) { if (typeof value.then === 'function' ) { return true } else { return false } } else { return false } }
二、catch-finally
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Promise { catch (onrejected) { return this .then(null , onrejected) } finally (cb) { return this .then( res => Promise .resolve(cb()).then(() => res), err => Promise .resolve(cb()).catch(() => err) ) } }
三、resolve-reject
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Promise { static resolve (value) { return new Promise ((resolve, reject ) => { if (isPromise(value)) { value.then(resolve, reject) } else { resolve(value) } }) } static reject (value) { return new Promise ((resolve, reject ) => { reject(value) }) } }
四、race
Promise.race:谁先改变状态就返回谁的结果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Promise { static race (values) { return new Promise ((resolve, reject ) => { for (let i = 0 ; i < values.length; i++) { const cur = values[i] if (isPromise(cur)) { cur.then(resolve, reject) } else { resolve(cur) } } }) } }
五、all
Promise.all:状态都是fulfilled,返回所有结果,有一个rejected,就返回rejected结果。
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 class Promise { static all (values) { return new Promise ((resolve, reject ) => { let ret = [] let index = 0 function processData (i, val ) { ret[i] = val if (++index === values.length) { resolve(ret) } } for (let i = 0 ; i < values.length; i++) { const cur = values[i] if (isPromise(cur)) { cur.then(val => { processData(i, val) }, reject) } else { processData(i, cur) } } }) } }
六、allSettled
Promise.allSettled:状态总是fulfilled,记录所有成功失败结果。
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 class Promise { static allSettled (values) { return new Promise ((resolve, reject ) => { let ret = [] let index = 0 function processData (i, val, type ) { ret[i] = { status: type === 'value' ? FULFILLED : REJECTED, [type]: val } if (++index === values.length) { resolve(ret) } } for (let i = 0 ; i < values.length; i++) { const cur = values[i] if (isPromise(cur)) { cur.then(res => { processData(i, res, 'value' ) }, err => { processData(i, err, 'reason' ) }) } else { processData(i, cur, 'value' ) } } }) } }
七、any
Promise.any:有一个fulfilled,就返回fulfilled的结果,都rejected,则返回rejecte。
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 class Promise { static any (values) { return new Promise ((resolve, reject ) => { let errData = [] let index = 0 function processError (i, err ) { errData[i] = err if (++index === values.length) { reject("AggregateError: All promises were rejected" ) } } for (let i = 0 ; i < values.length; i++) { const cur = values[i] if (isPromise(cur)) { cur.then(resolve, err => { processError(i, err) }) } else { resolve(cur) } } }) } }
参考链接