Promise在日常的开发中频繁的使用到,并且在面试的过程中也会被当做知识点经常提问到
Promise概述
在Promise出现之前,我们会使用回调函数来处理异步操作的结果,回调函数本身并没有什么问题,只是当业务逻辑比较深且复杂时,会产生“回调地狱”,对后期的重构和维护很不友好
Promise的结构和使用
首先我们看看,Promise平时的使用,好帮助我们下面更好的去理解每个代码部分的效果和功能。详细的解答和思路都在注释内。
let exp = new Promise((resolve, reject) {
console.log("Promise is running");
setTimeout(()=>{
resolve("Tom is coming")
}, 2000)
})
exp.then((res) => {
console.log(res); // Tom is coming
}, (err) => {
// 处理报错异常 接收reject的参数
})
Promise的三个状态(pending, fullfilled, rejected)
- pending 进行中
- fullfilled 已完成
- rejected 截获报错信息并传递给reject
- Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected,只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为已定型
具体实现
class MyPromise {
static pending = "pending"
static success = "fullfilled"
static error = "rejected"
contructor(executor) {
// 初始化状态
this.status = MyPromise.pending
this.value = undefined // 初始化值
this.errMsg = undefined // 初始化错误信息
this.callbacks = [] // 考虑到异步请求promise的状态还未完成变更的情况
// 将需执行的函数当做传参传入自己的Promise中
executor(this._resolve.bind(this), this._reject.bind(this))
}
// 因为异步请求先需要执行resolve或reject改变状态后才能拿到需要的值,所以暂将其存入callbacks中,等待其执行完毕,再执行callbacks中的内容。每调用一次then就会向callbacks中推入一个新的待执行的
then(onFullfilled, onRejected) {
this.callbacks.push({
onFullfilled, onRejected})
}
// 已完成
_resolve(value) {
this.status = MyPromise.success // 将状态更新为已完成
this.value = value
// 执行callbacks队列中的内容
this.callbacks.forEach(cb => this._handler(cb))
}
// 报错
_reject(err) {
this.status = MyPromise.error
this.errMsg = err
this.callbacks.forEach(cb => this._handler(cb))
}
// 用来处理异步数组的 也就是this.callbacks
_handler(cb) {
const {onFullfilled, onRejected} = cb
if(this.status === MyPromise.success && onFullfilled) {
// 执行成功
onFullfilled(this.value)
}
if(this.status === MyPromise.error && onRejected) {
// 报错信息
onRejected(this.errMsg)
}
}
}