手写 promise
简单版实现
代码
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
| const PENDING = 'PENDING'; const FULFILLED = 'FULFILLED'; const REJECTED = 'REJECTED';
function MyPromise(fn) { this.state = PENDING; this.resolveCallback = []; this.rejectCallback = []; this.value = null;
const resolve = (value) => { if (this.state === PENDING) { this.resolveCallback.map((each) => each(value)); this.value = value; this.state = FULFILLED; } };
const reject = (value) => { if (this.state === PENDING) { this.rejectCallback.map((each) => each(value)); this.value = value; this.state = REJECTED; } };
try { fn(resolve, reject); } catch (e) { reject(e); } }
MyPromise.prototype.then = function (onFulfilled, onRejected) { const onFulfilledCallback = typeof onFulfilled === 'function' ? onFulfilled : (x) => x; const onRejectedCallback = typeof onRejected === 'function' ? onRejected : (r) => { throw r; };
if (this.state === PENDING) { this.resolveCallback.push(onFulfilledCallback); this.rejectCallback.push(onRejectedCallback); }
if (this.state === FULFILLED) { onFulfilled(this.value); }
if (this.state === REJECTED) { onRejected(this.value); }
return this; };
|
测试用例 1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| const p1 = new MyPromise((resolve, reject) => { setTimeout(() => { resolve('hello'); }, 1000); }) .then('world') .then(console.log);
setTimeout(() => { p1.then(console.log); }, 2000);
|
测试用例 2
1 2 3 4 5 6 7 8 9
| const p2 = new MyPromise((resolve, reject) => { setTimeout(() => { reject('error'); }, 1000); }).then(null, (error) => { console.log(`error: `, error); });
|
Promise.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 25 26 27 28
| Promise.myAll = function (promises) { let count = 0; return new Promise((resolve, reject) => { let result = new Array(promises.length); for (let i = 0; i < promises.length; i += 1) { const promise = promises[i]; if (promise instanceof Promise) { promise .then((res) => { result[i] = res; count += 1; if (count === promises.length) { resolve(result); } }) .catch((err) => { reject(err); }); } else { result[i] = promise; count += 1; if (count === promises.length) { resolve(result); } } } }); };
|
测试 case
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
| const p1 = new Promise((resolve) => { setTimeout(() => { resolve('hello'); }, 1000); });
const p2 = new Promise((resolve) => { setTimeout(() => { resolve('world'); }, 500); });
const p3 = 999;
const p4 = Promise.reject('this is an error');
Promise.myAll([p1, p2, p3]).then((res) => { console.log(`res: `, res); });
Promise.myAll([p1, p2, p3, p4]) .then((res) => { console.log(`res: `, res); }) .catch((error) => { console.log(`error: `, error); })
|
Promise.allSettled 和 Promise.race 原理类似