先看日常我们是怎么使用Promise的
// 决议为成功
var p = new MyPromise(function (resolve, reject) {
resolve(42)
})
p.then(function fulfilled (v) {
console.log(v)
})
// 决议为拒绝
var p = new MyPromise(function (resolve, reject) {
reject(new Error('fail'))
})
p.then(null, function rejected(error) {
console.error(error)
})从以上代码分析Promise API的特点:
Promise构造函数接受一个函数作为参数,这个函数又接受两个内置方法作为参数,分别是resolve和reject,有三种状态,初始值为pending态,还有完成态fulfilled和拒绝态rejected
有then、resolve、reject三大核心方法
resolve方法使Promise决议为完成状态,存储传入的参数值,若传入的参数值为普通值,则不处理,若传入的参数值是Promise对象,则会展开这个对象,取出里面的普通值
then方法接受两个函数作为参数,如果没有就启用默认函数,若promise的决议是完成态,就调用完成函数,若Promise的决议是拒绝态,就调用拒绝函数,并把promise决议后的返回值传给回调函数,最后返回一个新的Promise对象
reject方法使Promise决议为拒绝态,记录传入的参数,但是并不像resolve那样对传入的promise对象展开
根据以上特点,我们开始自定义Promise
class MyPromise {
constructor (fn) {
this.state = 'pending' // 决议态
this.value = null // 记录resolve和reject的参数值
this.resolve = this.resolve.bind(this)
this.reject = this.reject.bind(this)
fn(this.resolve, this.reject) // 执行回调,并传入内置方法resolve和reject
}
}构造函数创建完毕,接下来开始构建then方法
class MyPromise {
constructor (fn) {
this.state = 'pending' // 决议态
this.value = null // 记录resolve和reject的参数值
this.resolve = this.resolve.bind(this)
this.reject = this.reject.bind(this)
fn(this.resolve, this.reject) // 执行回调,并传入内置方法resolve和reject
}
then (fulfilled, rejected) {
fulfilled = typeof fulfilled === 'function' ? fulfilled : (v => v)
rejected = typeof rejected === 'function' ? rejected : (v => {throw (v)})
if (this.state === 'fulfilled') {
fulfilled(this.value)
} else if (this.state === 'rejected') {
rejected(this.value)
}
new MyPromise(this.resolve, this.reject)
}
}紧接着开始构建resolve方法
class MyPromise {
constructor (fn) {
this.state = 'pending' // 决议态
this.value = null // 记录resolve和reject的参数值
this.resolve = this.resolve.bind(this)
this.reject = this.reject.bind(this)
fn(this.resolve, this.reject) // 执行回调,并传入内置方法resolve和reject
}
then (fulfilled, rejected) {
fulfilled = typeof fulfilled === 'function' ? fulfilled : (v => v)
rejected = typeof rejected === 'function' ? rejected : (v => {throw (v)})
if (this.state === 'fulfilled') {
fulfilled(this.value)
} else if (this.state === 'rejected') {
rejected(this.value)
}
new MyPromise(this.resolve, this.reject)
}
resolve (value) {
this.state = 'fulfilled'
if (value instanceof MyPromise) {
value.then((v) => {
this.value = v // 注意这里一定要用箭头函数,否则this会是undefined
})
} else {
this.value = value
}
}
}现在只剩下最简单的reject方法了
class MyPromise {
constructor (fn) {
this.state = 'pending' // 决议态
this.value = null // 记录resolve和reject的参数值
this.resolve = this.resolve.bind(this)
this.reject = this.reject.bind(this)
fn(this.resolve, this.reject) // 执行回调,并传入内置方法resolve和reject
}
then (fulfilled, rejected) {
fulfilled = typeof fulfilled === 'function' ? fulfilled : (v => v)
rejected = typeof rejected === 'function' ? rejected : (v => {throw (v)})
if (this.state === 'fulfilled') {
fulfilled(this.value)
} else if (this.state === 'rejected') {
rejected(this.value)
}
new MyPromise(this.resolve, this.reject)
}
resolve (value) {
this.state = 'fulfilled'
if (value instanceof MyPromise) {
value.then((v) => {
this.value = v // 注意这里一定要用箭头函数,否则this会是undefined
})
} else {
this.value = value
}
}
reject (value) {
this.state = 'rejected'
this.value = value
}
}至此自定义Promise已经实现完毕,让我们来用这个MyPromise写个使用demo
var p1 = new MyPromise(function (resolve, reject) {
resolve(42)
})
var p2 = new MyPromise(function (resolve, reject) {
resolve(p1)
})
p2.then(function fulfilled (v) {
console.log(v); // 42
})var p = new MyPromise(function (resolve, reject) {
reject(new Error('fail'))
})
p.then(null, function rejected(error) {
console.error(error) // Error: fail
})掌握一个skill最好的方式就是实现它
Done !