一、目标效果
本篇文章将实现一个名为MyPromise的类,可以实现如下的调用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| var p1 = new MyPromise((resolve, reject) => { setTimeout(() => { resolve(1) }, 1000) })
var p2 = p1.then(res => { return new MyPromise((resolve, reject) => { setTimeout(() => { resolve(res + 1) }, 1000) }) }) .then(res => { console.log(res) return res + 1 })
p1.then(res => { console.log(res) })
|
二、代码实现
本实例会实现Promise的构造函数,then函数,resolve和reject,以及all和race。
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
| const PENDING = 'PENDING' const FULFILLED = 'FULFILLED' const REJECTED = 'REJECTED'
class MyPromise { constructor(fn) { this.status = PENDING this.value = value this.reason = reason
this.resolveCallbacks = [] this.rejectCallbacks = []
const resolve = value => { if (this.status === PENDING) { this.status = FULFILLED this.value = value this.resolveCallbacks.forEach(fn => fn(this.value)) } }
const reject = reason => { if (this.status === PENDING) { this.status = REJECTED this.reason = reason this.rejectCallbacks.forEach(fn => fn(this.reason)) } }
try { fn(resolve, reject) } catch(err) { reject(err) } }
then(onFulfilled, onRejected) { onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw(new Error(reason)) }
const self = this
return new MyPromise((resolve, reject) => { let fulfilled = () => { try { const result = onFulfilled(self.value) return result instanceof MyPromise ? result.then(resolve, reject) : resolve(result) } catch (err) { reject(err) } }
let rejected = () => { try { const result = onRejected(self.value) return result instanceof MyPromise ? result.then(resolve, reject) : reject(result) } }
switch(self.status) { case PENDING: self.resolveCallbacks.push(fulfilled) self.rejectCallbacks.push(rejected) break case FULFILLED: fulfilled() break case REJECTED: rejected() break } }) }
catch(onRejected) { return this.then(null, onRejected) }
static resolve(value) { if (value instanceof MyPromise) { return value } else { return new MyPromise((resolve, reject) => resolve(value)) } }
static reject(reason) { return new MyPromise((resolve, reject) => reject(reason)) }
static all(promiseArr) { const len = promiseArr.length const values = new Array(len)
let count = 0
return new MyPromise((resolve, reject) => { for (let i = 0; i < len; i ++) { MyPromise.resolve(promiseArr[i]).then(val => { values[i] = val count ++ if (count === len) resolve(values) }, err => { reject(err) }) } }) }
static race(promiseArr) { return new MyPromise((resolve, reject) => { promiseArr.forEach(item => { MyPromise.resolve(item).then( val => resolve(val), err => reject(err) ) }) }) } }
|
参考:
Promise.then是如何实现链式调用的