1、优化then方法的抛异常问题
2、根据then方法接收的两个函数参数的返回值类型进行不同的数据处理
// promise/A+规范中说明promise有三种状态,且状态一旦被改变就不能再次发生变化
const PENDING = 'Pending'
const FULFILLED = 'Fulfilled'
const REJECTED = 'Rejected'
class Promise {
// 高阶函数,函数的参数是函数,高阶函数可以实现参数的预置
// 函数的参数中的函数为函数的声明
// executor是立即执行的函数,参数被预置在了constructor中
constructor(executor) {
this.state = PENDING
this.value = undefined // 成功的结果
this.reason = undefined // 失败的理由
// 解决then可以多次调用的问题
this.onResolvedCallbacks = []
this.onRejectedCallbacks = []
const resolve = (value) => {
if(this.state === PENDING) {
this.state = FULFILLED
this.value = value
// 当状态变化时再执行回调函数
this.onResolvedCallbacks.forEach(cb => cb(value))
}
}
const reject = (reason) => {
if(this.state === PENDING) {
this.state = REJECTED
this.reason = reason
// 当状态变化时再执行回调函数
this.onRejectedCallbacks.forEach(cb => cb(reason))
}
}
// 此处为executor函数的调用。参数传入resolve和reject两个函数
try {
executor(resolve, reject)
} catch(err) {
reject(err)
}
}
then(onFulfilledCallback, onRejectedCallback) {
onFulfilledCallback = typeof onFulfilledCallback === 'function' ? onFulfilledCallback : value => value
// 优化抛异常
onRejectedCallback = typeof onRejectedCallback === 'function' ? onRejectedCallback : reason => { throw reason }
// 可以链式调用,则then返回的必须是一个Promise
let promise = new Promise((resolve, reject) => {
if(this.state === FULFILLED) {
// 优化捕捉异常
setTimeout(() => {
try {
let res = onFulfilledCallback(this.value)
// 根据res的不同类型做不同的处理
resolvePromise(promise, res, resolve, reject)
} catch(e) {
reject(e)
}
})
}
if(this.state === REJECTED) {
setTimeout(() => {
try {
let res = onRejectedCallback(this.reason)
resolvePromise(promise, res, resolve, reject)
} catch(e) {
reject(e)
}
})
}
// 当executor出现异步任务时,then执行的时候,状态还未发生变化,可以将回调放到回调函数数组中
if(this.state === PENDING) {
this.onResolvedCallbacks.push((value) => {
setTimeout(() => {
try {
let res = onFulfilledCallback(value)
resolvePromise(promise, res, resolve, reject)
} catch(e) {
reject(e)
}
})
})
this.onRejectedCallbacks.push((reason) => {
setTimeout(() => {
try {
let res = onRejectedCallback(reason)
resolvePromise(promise, res, resolve, reject)
} catch(e) {
reject(e)
}
})
})
}
})
return promise
}
}
// 根据不同的res类型进行不同的处理
function resolvePromise(promise, res, resolve, reject) {
if(res === promise) {
return reject(new TypeError('死循环'))
}
if(res instanceof Promise) {
try {
res.then(x => {
resolvePromise(promise, x, resolve, reject)
// resolve(x)
})
} catch(e) {
reject(e)
}
} else {
resolve(res)
}
}
let p = new Promise((resolve, reject) => {
console.log(2)
setTimeout(() => {
resolve(1)
}, 0)
})
let p2 = new Promise((resolve, reject) => {
resolve(3)
})
let then = p.then(res => {
console.log(res)
return p2
}).then(res => {
console.log(res)
})
console.log(5)
// 2, 5, 1, 3