前言
- 想手写实现一个Promise先要知道Promise的原理和他内部的流程
- 我们知道的
Promise就是一个异步对象,可以传入一个带有resolve, reject参数的函数。
Promise里还有自己的状态,Pending 为初始的状态,Fulfilled 为成功的状态,Rejected 为失败的状态。
- 这里的状态是不可逆的,就是一个
Promise对象状态一旦发生改变就不会再转换回去,这里其实就为我们后续调用的函数提供了保证。(PS: Promise对象里的代码是同步执行的)
不同状态有与之对应的实例方法来执行后续的逻辑
promise.then():获取异步任务的正常结果,
promise.catch():获取异步任务的异常结果,
promise.finaly():异步任务无论成功与否,都会执行。
Promise还有一个很重要的链式调用,就是Promise的返回都是一个Promise对象,可以继续执行后续的状态方法的调用。如果逻辑需要中断可以在需要中断的地方手动的抛出一个throw错误来中断链式调用。
- 还有两个使用的方法
promise.all (): 并发处理多个异步任务,所有任务都执行成功,才能得到结果
promise.race (): 并发处理多个异步任务,只要有一个任务执行成功,就能得到结果
补充一些Class类的知识:
class中可以看到里面有一个constructor()方法,这就是构造方法,而this关键字则代表实例对象。
class类除了构造方法constructor,还能定义其他方法。注意,如定义toString()方法的时候,前面不需要加上function这个关键字,直接把函数定义放进去了就可以了。另外,方法与方法之间不需要逗号分隔,加了会报错。
- 获取原型链上的方法
Object.getOwnPropertyNames(Point.prototype)
constructor()方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。一个类必须有constructor()方法,如果没有显式定义,一个空的constructor()方法会被默认添加。
constructor()方法默认返回实例对象(即this),完全可以指定返回另外一个对象。
- 类必须使用
new调用,否则会报错。这是它跟普通构造函数的一个主要区别
步入正题,手撕Promise
class Promise1 {
constructor(executor) {
this.status = 'pending'
this.success = null
this.error = null
this.resolvedCallback = []
this.rejectCallback = []
let resolve = (value) => {
if (this.status === 'pending') {
this.status = 'fulfilled'
this.success = value
this.resolvedCallback.forEach(fn => fn())
}
}
let reject = (value) => {
if (this.status === 'pending') {
this.status = 'reject'
this.error = value
this.rejectCallback.forEach(fn => fn())
}
}
try {
executor(resolve, reject)
} catch (e) {
reject(e)
}
}
then (onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : () => { }
onRejected = typeof onRejected === 'function' ? onRejected : () => { }
let promise2 = new Promise1((resolve, reject) => {
if (this.status === 'fulfilled') {
let data = onFulfilled(this.success)
}
if (this.status === 'rejected') {
onRejected(this.error)
}
if (this.status === 'pending') {
this.resolvedCallback.push(() => { onFulfilled(this.success) })
this.rejectCallback.push(() => { onRejected(this.error) })
}
})
return promise2
}
catch () {
onRejected(this.error)
}
}
const p = new Promise1((resolve, reject) => {
reject('返回失败s')
})
p.then((value) => {
console.log(value)
})
p.catch(value => {
console.log(value)
})
console.log(p)