一、实现思路
- Promise 是一个类或函数;
- 构造函数接收的参数是一个 excutor 函数;
- 这个函数的参数是 resolve 和 reject 两个内部函数;
- 构建 resolve 和 reject 并传入 excutor,并使之立即执行;
- executor 参数是两个函数,用于描述 promise实例的状态;
- resolve 表示成功,可以传入一个 value;
- reject 表示失败,可以传入一个 reason;
- 每个 Promise 实例都有一个 then 方法;
- promise 一旦状态发生后,不能再更改
- promise 有三种状态:成功态,失败态,等待态(默认)
- 在 resolve 和 reject 中修改 status 状态;
- Promise 类中包含 then 和 catch 等方法;
class myPromise {
constructor(fun) {
this.status = 'pending' // status:pending、fulfilled、rejected
fun(this.resolve, this.reject) // 主体函数将会被立即执行
}
resolve() {}
reject() {}
then() {}
catch() {}
}
二、三种状态切换和对应状态函数调用
// 声明 promise 三种状态
const PENDING = 'PENDING' // 等待态
const FULFILLED = 'FULFILLED' // 成功态
const REJECTED = 'REJECTED' // 失败态
class myPromise {
// 通过 new 进行实例化时,传入 executor 执行器函数
constructor(executor) {
this.value = undefined // 成功的原因
this.reason = undefined // 失败的原因
this.state = PENDING // promise 状态,默认等待态
// 成功 reslove 函数、失败reject函数,并传入executor
const reslove = (value) => {
// 等待态 --> 成功态
if (this.state === PENDING) {
this.value = value
this.state = FULFILLED
}
}
const reject = (reason) => {
// 等待态 --> 失败态
if (this.state === PENDING) {
this.reason = reason
this.state = REJECTED
}
}
// 立即执行 executor 执行器函数,通过 try...catch... 进行异常捕捉;
try {
executor(reslove, reject)
} catch (e) {
reject(e) // 有异常,调用 reject 更新为失败态
}
}
// 定义 then 方法:包含两个参数 onFulfilled 和 onRejected;
// 根据 Promise 状态,执行 onFulfilled 或 onRejected;
then(onFulfilled, onRejected) {
// 成功态,调用 onFulfilled,传入成功 value
if (this.state === DULFILLED) {
onFulfilled(this.value)
}
// 失败态,执行 onRejected,传入失败 reason
if (this.state === REJECTED) {
onRejected(this.reason)
}
}
}
测试一下
let promise = new myPromise((resolve, reject)=>{
console.log('promise')
throw new Error("抛出错误");
})
promise.then((value)=>{
console.log('success', value)
},(reason)=>{
console.log('err', reason)
})
console.log('ok')
运行结果
promise
err Error: 抛出错误
ok
很明显,没有按照预期的执行结果(先同步后异步),别着急,紧接着往下看。。。
三、对异步操作的支持
采用发布订阅的思想
- 事件订阅:收集回调函数
constructor(executor) {
this.onResolvedCallbacks = [] // 收集成功回调
this.onRejectedCallbacks = [] // 收集失败回调
}
then(onFulfilled, onRejected) {
if (this.state === PENDING) {
this.onResolvedCallbacks.push(() => {
onFulfilled(this.value) // 传入 value
})
this.onRejectedCallbacks.push(() => {
onRejected(this.value) // 传入 value
})
}
}
- 事件发布:根据状态执行回调处理
then(onFulfilled, onRejected) {
if (this.state === PENDING) {
this.onResolvedCallbacks.push(() => {
onFulfilled(this.value) // 传入 value
})
this.onRejectedCallbacks.push(() => {
onRejected(this.reason) // 传入 value
})
}
}
四、promise的链式调用
链式调用分为几种情况
- 成功回调中,返回普通值
结论:成功回调中返回普通值,会进入下一个 then 的成功回调
let promise = new Promise((resolve, reject) => {
setTimeout(() => {
// 异步操作
resolve('执行成功') // 进入成功回调处理
}, 1000)
})
promise
.then(
(value) => {
console.log('[then1-onFulfilled]', value)
return 'then1-onFulfilled:' + value
// return new Error() // 返回普通值
// return undefined // 返回普通值
},
(reson) => {
console.log('[then1-onRejected]', reson)
}
)
.then(
(value) => {
console.log('[then2-onFulfilled]', value)
},
(reson) => {
console.log('[then2-onRejected]', reson)
}
)
// 执行结果
// [then1-onFulfilled] 执行成功
// [then2-onFulfilled] then1-onFulfilled:执行成功
- 失败回调中,返回普通值
结论:失败回调中返回普通值,会进入下一个 then 的成功回调
let promise = new Promise((resolve, reject) => {
setTimeout(() => {
reject('执行失败') // 进入失败回调处理
}, 1000)
})
promise
.then(
(value) => {
console.log('[then1-onFulfilled]', value)
return 'then1-onFulfilled:' + value
},
(reson) => {
console.log('[then1-onRejected]', reson)
return 'then1-onRejected:' + reson // 返回普通值
// return new Error() // 返回普通值
// return undefined // 返回普通值
}
)
.then(
(value) => {
console.log('[then2-onFulfilled]', value)
},
(reson) => {
console.log('[then2-onRejected]', reson)
}
)
// [then1-onRejected] 执行失败
// [then2-onFulfilled] then1-onRejected:执行失败
- 成功回调中,抛出异常
结论:成功回调中抛出异常,会进入下一个 then 的失败回调
let promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('执行成功')
}, 1000)
})
promise
.then(
(value) => {
console.log('[then1-onFulfilled]', value)
throw new Error('抛出异常')
},
(reson) => {
console.log('[then1-onRejected]', reson)
return 'then1-onRejected:' + reson
}
)
.then(
(value) => {
console.log('[then2-onFulfilled]', value)
},
(reson) => {
console.log('[then2-onRejected]', reson)
}
)
// [then1-onFulfilled] 执行成功
// [then2-onRejected] Error: 抛出异常
- 失败回调中,抛出异常
结论:失败回调中抛出异常,会进入下一个 then 的失败回调
let promise = new Promise((resolve, reject) => {
setTimeout(() => {
reject('执行失败')
}, 1000)
})
promise
.then(
(value) => {
console.log('[then1-onFulfilled]', value)
},
(reson) => {
console.log('[then1-onRejected]', reson)
throw new Error('抛出异常')
}
)
.then(
(value) => {
console.log('[then2-onFulfilled]', value)
},
(reson) => {
console.log('[then2-onRejected]', reson)
}
)
// [then1-onRejected] 执行失败
// [then2-onRejected] Error: 抛出异常
- executor 执行器中报错
结论:executor同步逻辑抛出异常,进入 then 失败处理
let promise = new Promise((resolve, reject) => {
throw new Error('executor 同步报错') // 抛出异常
resolve('处理成功') // 不会被执行
})
promise
.then(
(value) => {
console.log('[then1-onFulfilled]', value)
},
(reson) => {
console.log('[then1-onRejected]', reson)
}
)
.then(
(value) => {
console.log('[then2-onFulfilled]', value)
},
(reson) => {
console.log('[then2-onRejected]', reson)
}
)
// [then1-onRejected] Error: executor 同步报错
// [then2-onFulfilled] undefined
- 总结
- Promise 的链式调用,当调用 then 方法后,将会返回一个全新的 promise 实例;
- then 中方法(无论成功还是失败)返回普通值,都会做为下一次 then 的成功结果;
- 执行器函数 和 then 中方法(无论成功还是失败)抛出异常,都会进入下一次 then 的失败结果;
代码实现
1. 获取 then 回调处理返回值
出现问题:作用域不同,无法获取x值
then(onFulfilled, onRejected) {
if (this.state === PENDING) {
this.onResolvedCallbacks.push(() => {
let x = onFulfilled(this.value) // 传入 value
})
this.onRejectedCallbacks.push(() => {
let x = onRejected(this.reason) // 传入 value
})
}
// 成功态,调用 onFulfilled,传入成功 value
if (this.state === FULFILLED) {
// 拿到回调处理的返回值
let x = onFulfilled(this.value)
}
// 失败态,执行 onRejected,传入失败 reason
if (this.state === REJECTED) {
let x = onRejected(this.reason)
}
// 包装回调处理的返回值 x ,成为一个全新的 Promise 实例
let promise2 = new Promise((resolve, reject) => {
// 问题:拿不到 x,不在一个作用域中
})
// 返回新的 promise 实例
return promise2
}
2. then 返回全新 promise
需要在 promise2 的 executor 执行器中拿到返回值解决上述问题
then(onFulfilled, onRejected) {
let promise2 = new myPromise((reslove, reject) => {
if (this.state === PENDING) {
this.onResolvedCallbacks.push(() => {
let x = onFulfilled(this.value) // 传入 value
reslove(x)
})
this.onRejectedCallbacks.push(() => {
let x = onRejected(this.reason) // 传入 value
reslove(x)
})
}
// 成功态,调用 onFulfilled,传入成功 value
if (this.state === FULFILLED) {
// 拿到回调处理的返回值
let x = onFulfilled(this.value)
reslove(x)
}
// 失败态,执行 onRejected,传入失败 reason
if (this.state === REJECTED) {
let x = onRejected(this.reason)
reslove(x)
}
})
// 返回新的 promise 实例
return promise2
}
3. 对异常的处理
then(onFulfilled, onRejected) {
let promise2 = new myPromise((reslove, reject) => {
if (this.state === PENDING) {
this.onResolvedCallbacks.push(() => {
try {
let x = onFulfilled(this.value) // 传入 value
reslove(x)
} catch (error) {
reject(error)
}
})
this.onRejectedCallbacks.push(() => {
try {
let x = onRejected(this.reason) // 传入 value
reslove(x)
} catch (error) {
reject(error)
}
})
}
// 成功态,调用 onFulfilled,传入成功 value
if (this.state === FULFILLED) {
// 拿到回调处理的返回值
try {
let x = onFulfilled(this.value) // 传入 value
reslove(x)
} catch (error) {
reject(error)
}
}
// 失败态,执行 onRejected,传入失败 reason
if (this.state === REJECTED) {
try {
let x = onRejected(this.reason) // 传入 value
reslove(x)
} catch (error) {
reject(error)
}
}
})
// 返回新的 promise 实例
return promise2
}
五、全部代码
// 声明 promise 三种状态
const PENDING = 'PENDING' // 等待态
const FULFILLED = 'FULFILLED' // 成功态
const REJECTED = 'REJECTED' // 失败态
class myPromise {
// 通过 new 进行实例化时,传入 executor 执行器函数
constructor(executor) {
this.value = undefined // 成功的原因
this.reason = undefined // 失败的原因
this.state = PENDING // promise 状态,默认等待态
this.onResolvedCallbacks = [] // 收集成功回调
this.onRejectedCallbacks = [] // 收集失败回调
// 成功 reslove 函数、失败reject函数,并传入executor
const reslove = (value) => {
// 等待态 --> 成功态
if (this.state === PENDING) {
this.value = value
this.state = FULFILLED
// 事件发布操作
this.onResolvedCallbacks.forEach((fn) => fn())
}
}
const reject = (reason) => {
// 等待态 --> 失败态
if (this.state === PENDING) {
this.reason = reason
this.state = REJECTED
// 事件发布操作
this.onRejectedCallbacks.forEach((fn) => fn())
}
}
// 立即执行 executor 执行器函数,通过 try...catch... 进行异常捕捉;
try {
executor(reslove, reject)
} catch (e) {
reject(e) // 有异常,调用 reject 更新为失败态
}
}
// 定义 then 方法:包含两个参数 onFulfilled 和 onRejected;
// 根据 Promise 状态,执行 onFulfilled 或 onRejected;
then(onFulfilled, onRejected) {
let promise2 = new myPromise((reslove, reject) => {
if (this.state === PENDING) {
this.onResolvedCallbacks.push(() => {
try {
let x = onFulfilled(this.value) // 传入 value
reslove(x)
} catch (error) {
reject(error)
}
})
this.onRejectedCallbacks.push(() => {
try {
let x = onRejected(this.reason) // 传入 value
reslove(x)
} catch (error) {
reject(error)
}
})
}
// 成功态,调用 onFulfilled,传入成功 value
if (this.state === FULFILLED) {
// 拿到回调处理的返回值
try {
let x = onFulfilled(this.value) // 传入 value
reslove(x)
} catch (error) {
reject(error)
}
}
// 失败态,执行 onRejected,传入失败 reason
if (this.state === REJECTED) {
try {
let x = onRejected(this.reason) // 传入 value
reslove(x)
} catch (error) {
reject(error)
}
}
})
// 返回新的 promise 实例
return promise2
}
}