前言
有了上一篇对Promise的简易实现,我们大概了解了如何手写一个MyPromise,这里接着上一篇的内容,继续完善MyPromise剩余的功能函数,并且从中体会和加深对Promise的理解,在实际应用中更能知根知底~
MyPromise.resolve
按照对Promise的理解,这里只要直接返回一个『同步』的MyPromise实例就行了~
1 2 3 4 5 6 7 8
| class MyPromise { static resolve(val) { return new MyPromise((resolveFn, rejectFn) => { resolveFn(val); }); } }
|
MyPromise.reject
和resolve一样,换成reject就行了~
1 2 3 4 5 6 7 8
| class MyPromise { static reject(reason) { return new MyPromise((resolveFn, rejectFn) => { rejectFn(reason); }); } }
|
MyPromise.all
all的作用不用多说,我们直接来看实现吧~
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| class MyPromise { static all(promises) { return new MyPromise((resolve, reject) => { try { const len = promises.length; const result = new Array(len); let count = 0; for (let i = 0; i < len; i += 1) { const p = promises[i]; p.then(res => { result[i] = res; count += 1; if (count === len) { resolve(result); } }); } } catch(e) { reject(e.message); } }); } }
|
MyPromise.race
好了,最后就剩下race啦,比起all,先到先得,更简单了~
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class MyPromise { static race(promises) { return new MyPromise((resolve, reject) => { try { for (let i = 0; i < promises.length; i += 1) { const p = promises[i]; p.then(res => { resolve(res); }); } } catch(e) { reject(e.message); } }); } }
|
MyPromise源码
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 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
| const PENDDING = "pedding"; const FULFILLMENT = "fulfillment"; const REJECTION = "rejection";
class MyPromise { static resolve(val) { return new MyPromise((resolveFn, rejectFn) => { resolveFn(val); }); }
static reject(reason) { return new MyPromise((resolveFn, rejectFn) => { rejectFn(reason); }); }
static all(promises) { return new MyPromise((resolve, reject) => { try { const len = promises.length; const result = new Array(len); let count = 0; for (let i = 0; i < len; i += 1) { const p = promises[i]; p.then(res => { result[i] = res; count += 1; if (count === len) { resolve(result); } }); } } catch(e) { reject(e.message); } }); }
static race(promises) { return new MyPromise((resolve, reject) => { try { for (let i = 0; i < promises.length; i += 1) { const p = promises[i]; p.then(res => { resolve(res); }); } } catch(e) { reject(e.message); } }); }
constructor(executor) { this.status = PENDDING; this.value = null; this.reason = null;
this.resolveQueue = []; this.rejectQueue = [];
const resolve = (val) => { if (this.status === PENDDING) { this.status = FULFILLMENT; this.value = val; while(this.resolveQueue.length) { const res = this.resolveQueue.shift(); res(val); } } };
const reject = (reason) => { if (this.status === PENDDING) { this.status = REJECTION; this.reason = reason; while(this.rejectQueue.length) { const rej = this.rejectQueue.shift(); rej(reason); } } }
try { executor(resolve, reject); } catch(e) { reject(e.message); } }
then(onResolve, onReject) { onResolve = typeof onResolve === 'function' ? onResolve : val => val; onReject = typeof onReject === 'function' ? onReject : reason => { reason = reason instanceof Error ? reason.message : reason; throw new Error(reason); }; return new MyPromise((resolveFn, rejectFn) => { const fuifillmentFn = (val) => { try { const result = onResolve(val); if (result instanceof MyPromise) { result.then(resolveFn, rejectFn); } else { resolveFn(result); } } catch(e) { rejectFn(e instanceof Error ? e.message: e); } };
const rejectionFn = (reason) => { try { const result = onReject(reason); if (result instanceof MyPromise) { result.then(resolveFn, rejectFn); } else { rejectFn(result); } } catch(e) { rejectFn(e instanceof Error ? e.message: e); } };
if (this.status === PENDDING) { this.resolveQueue.push(fuifillmentFn); this.rejectQueue.push(rejectionFn); } if (this.status === FULFILLMENT) { fuifillmentFn(this.value) } if (this.status === REJECTION) { rejectionFn(this.reason); } }); }
catch(reject) { this.then(null, reject); } }
const p = new MyPromise((resolve, reject) => { setTimeout(() => { console.log('resolve:hello world'); resolve('hello world') }, 1000); });
p.then(res => { console.log('then:', res); return new MyPromise((resolve, reject) => { setTimeout(() => { resolve(`${res},hello js11`); }, 1000); }) }) .then() .then(res => { console.log('经过透传:', res); }) setTimeout(() => { MyPromise.resolve('静态resolve').then(res => console.log(res)) }, 1000) console.time(); const list = [ new MyPromise((resolve, reject) => { setTimeout(() => { console.log('test all: 1 done'); resolve('one') }, 5000); }), new MyPromise((resolve, reject) => { setTimeout(() => { console.log('test all: 2 done'); resolve('two') }, 3000); }), new MyPromise((resolve, reject) => { setTimeout(() => { console.log('test all: 3 done'); resolve('three') }, 2000); }), ]; MyPromise.all(list).then(res => { console.log('MyPromise.all===>', res); console.timeEnd(); }); MyPromise.race(list).then(res => { console.log('MyPromise.race===>', res); console.timeEnd(); });
|
总结
总体来说,比起上一篇,这一篇并没有过多的解释,因为知道Promise的功能,简易实现的代码都非常通俗易懂,而且没有什么太绕的逻辑。所以通过简易实现MyPromise,做一次温故知新,继续加油~