隨著ES6的出現(xiàn),Promise成為標準,平時使用的次數(shù)也增加洛勉。但是Promise的原理是什么,如何實現(xiàn)鏈式調(diào)用如迟。今天就來探究一下收毫,下面簡單實現(xiàn)了一個Promise:
class Promise {
constructor (fn) {
this.value = ''
this.resolveFn = null
this.rejectFn = null
try {
fn.call(this, this.resolve.bind(this), this.reject.bind(this))
} catch (e) {
this.reject.call(this, e)
}
}
resolve (value) {
this.value = value
setTimeout(() => {
this.resolveFn && this.resolveFn.call(this, value)
return this
}, 0)
}
reject (value) {
this.value = value
setTimeout(() => {
console.log(this)
this.rejectFn && this.rejectFn.call(this, value)
return this
}, 0)
}
then (onFullfilled, onRejected) {
this.resolveFn = onFullfilled
this.rejectFn = onRejected
return this
}
}
接下來來執(zhí)行一下:
var fn = new Promise((resolve, reject) => {
console.log(111)
resolve(333)
console.log(222)
})
fn.then((val) => {
console.log(val)
}, (e) => {
console.log(e)
})
// 111
// 222
// 333
執(zhí)行結(jié)果是正確的攻走,但是這段代碼有缺陷,只支持一個then方法此再,不支持多個then方法的調(diào)用昔搂,后面定義的then方法會覆蓋前面的方法。接下來來改造下:
class Promise {
constructor (fn) {
this.state = 'pending'
this.callbacks = []
try {
fn.call(this, this.resolve.bind(this), this.reject.bind(this))
} catch (e) {
this.value = e
this.reject.call(this, e)
}
}
resolve (value) {
this.state = 'fullfilled'
this.value = value
this.run()
}
reject (value) {
this.state = 'rejected'
this.value = value
this.run()
}
then (onFullFilled, onRejected) {
return new Promise((resolve, reject) => {
this.handle({
onFullFilled: onFullFilled,
onRejected: onRejected,
resolve: resolve,
reject: reject
})
})
}
catch (onRejected) {
this.state = 'rejected'
return this.then(undefined, onRejected)
}
run () {
setTimeout(() => {
this.callbacks.forEach(callback => {
this.handle(callback)
})
}, 0)
}
handle (callback) {
if (this.callbacks.length === 0) {
this.callbacks.push(callback)
return
}
let fn = this.state === 'fullfilled' ? callback.onFullFilled : callback.onRejected
if (!fn) {
fn = this.state === 'fullfilled' ? callback.resolve : callback.reject
fn(this.value)
return
}
try {
let res = fn(this.value)
callback.resolve(res)
} catch (e) {
this.value = e
callback.reject(e)
}
}
}
var fn = new Promise((resolve, reject) => {
console.log(111)
resolve(333)
console.log(222)
})
fn.then((val) => {
console.log(val)
}, (e) => {
console.log(e)
})
.then((e) => {
console.log(555)
throw new Error('Error11')
}, (e) => {
console.log(666)
})
.catch(e => {
console.log(e)
return 'aa'
})
.then((e) => {
console.log(e)
})
至此输拇,實現(xiàn)了Promise的簡單功能摘符。