Promise 是一种 JavaScript 异步编程的解决方案,它可以避免回调函数嵌套和代码可读性差的问题。Promise 是一个表示异步操作的对象,它有三种状态:Pending(等待态)、Resolved(成功态)、Rejected(失败态)。
Promise 的原理可以分为以下几个部分:
- Promise 对象的状态可以从 Pending 转变为 Resolved 或 Rejected,但一旦状态发生变化就无法再次改变。
- Promise 对象有一个 then 方法,可以注册 Resolved 或 Rejected 状态变化后的回调函数,它返回的是一个新的 Promise 对象。
- then 方法接受两个回调函数作为参数,第一个函数用于处理 Resolved 状态,第二个函数用于处理 Rejected 状态。
- 如果 then 方法的回调函数返回一个 Promise 对象,那么 then 方法返回的新 Promise 对象会等待该 Promise 对象的状态变化,然后根据该 Promise 对象的状态再次改变自身状态。
- 如果 then 方法的回调函数返回一个非 Promise 对象的值,那么 then 方法返回的新 Promise 对象状态为 Resolved,值为该非 Promise 对象的值。
- 如果 then 方法的回调函数抛出一个异常,那么 then 方法返回的新 Promise 对象状态为 Rejected,值为该异常。
Promise 的实现依赖于 JavaScript 的事件循环机制,它使用微任务(microtask)和宏任务(macrotask)来管理异步操作的执行顺序。当 Promise 对象的状态变化时,它会根据 Promise 对象的状态和注册的回调函数类型(Resolved 或 Rejected)将回调函数放入微任务队列或宏任务队列中,等待事件循环机制调度执行。
下面是代码实现过程
使用ts能够更好的对类进行标记与规范,这里使用了泛型类来实现的。
export default class CustomPromise<T> { private status: "pending" | "fulfilled" | "rejected" = "pending"; private results: T | undefined; private error: any; private resolveCbs: ((results: T) => void)[] = []; private rejectCbs: ((error: any) => void)[] = []; constructor (executor: (resolve: (results: T) => void, reject: (error: any) => void) => void) { executor(this.resolve.bind(this), this.reject.bind(this)) } // pending => fulfilled private resolve (results: T) { if (this.status === "pending") { this.status = "fulfilled" this.results = results this.resolveCbs.forEach(cb => cb(results)) } } // pending => rejected private reject (error: any) { // console.log("reject:外", error); // console.log(this.rejectCbs); if (this.status === "pending") { this.status = "rejected" this.error = error this.rejectCbs.forEach(cb => cb(error)) } } // 执行then 回调 public then (onSuccessFn?: (results: T | undefined) => void, onErrorFn?: (error: any) => void) { // 链式调用 => return Promise // 如果 then 方法的回调函数返回一个 Promise 对象,那么 then 方法返回的新 Promise 对象会等待该 Promise 对象的状态变化,然后根据该 Promise 对象的状态再次改变自身状态。 // 如果 then 方法的回调函数返回一个非 Promise 对象的值,那么 then 方法返回的新 Promise 对象状态为 Resolved,值为该非 Promise 对象的值。 // 如果 then 方法的回调函数抛出一个异常,那么 then 方法返回的新 Promise 对象状态为 Rejected,值为该异常。 const promise = new CustomPromise((resolve, reject) => { if (this.status === "fulfilled") { // 这里的 try catch 是为了验证.then函数是否能正常执行,以下同 try { const results = onSuccessFn ? onSuccessFn(this.results) : undefined resolve(results) } catch (error) { reject(error) } } else if (this.status === "rejected") { try { const results = onErrorFn ? onErrorFn(this.error) : undefined; resolve(results) } catch (error) { reject(error) } } else { this.resolveCbs.push((results) => { try { const newResults = onSuccessFn ? onSuccessFn(results) : undefined resolve(newResults) } catch (error) { reject(error) } }) this.rejectCbs.push((error) => { console.log(error); try { const newResult = onErrorFn ? onErrorFn(error) : undefined; resolve(newResult) } catch (error) { reject(error) } }) } }) return promise } // 执行catch 回调 public catch (onErrorFn?: (results: any) => void) { return this.then(undefined, onErrorFn) } }
复制
重点:
1、要对then函数深度解读
2、JavaScript 的事件循环机