如何使用js实现一个 Promise函数?

发布时间:2025-02-19
4346 字, 需阅读 9 分钟
已被阅读183

在 JavaScript 中,Promise 是一种用于处理异步操作的对象,提供了一种简洁的方式来管理异步任务的成功和失败结果。要实现一个自定义的 Promise 函数,你需要了解以下几个关键概念:

  1. Promise 构造函数:构造函数接收一个 executor 函数,executor 函数接受两个参数:resolverejectresolve 用于处理成功的结果,reject 用于处理失败的结果。

  2. Promise 状态Promise 可以处于以下三种状态之一:

    • pending(待定):初始状态,既不是成功,也不是失败。
    • fulfilled(已兑现):操作成功完成,resolve 被调用。
    • rejected(已拒绝):操作失败,reject 被调用。
  3. then 和 catch 方法Promise 对象提供 .then() 方法用于处理成功的结果,.catch() 方法用于处理失败的结果。每个 .then().catch() 方法都返回一个新的 Promise,可以进行链式调用。

实现自定义 Promise

下面是一个简化版的自定义 Promise 实现,演示如何实现 resolvereject,以及如何处理 .then().catch() 方法。

步骤:

  1. 定义 Promise 构造函数:我们需要将状态管理(pendingfulfilledrejected)保存在 Promise 实例中。
  2. then() 方法:每次 .then() 被调用时,都会返回一个新的 Promise,因此支持链式调用。
  3. resolve()reject():我们需要处理 resolvereject 的行为,确保状态转换正确并触发 .then().catch() 方法。

实现代码:

class MyPromise { constructor(executor) { this.state = 'pending'; // 初始状态是 pending this.value = undefined; // 存储异步操作的结果 this.reason = undefined; // 存储失败的原因 this.onResolvedCallbacks = []; // 存储成功的回调 this.onRejectedCallbacks = []; // 存储失败的回调 // resolve 函数,改变 Promise 状态为 fulfilled const resolve = (value) => { if (this.state === 'pending') { this.state = 'fulfilled'; this.value = value; // 执行所有的成功回调 this.onResolvedCallbacks.forEach((callback) => callback(value)); } }; // reject 函数,改变 Promise 状态为 rejected const reject = (reason) => { if (this.state === 'pending') { this.state = 'rejected'; this.reason = reason; // 执行所有的失败回调 this.onRejectedCallbacks.forEach((callback) => callback(reason)); } }; // 执行传入的 executor 函数 try { executor(resolve, reject); } catch (err) { reject(err); // 如果 executor 执行出错,直接调用 reject } } // then 方法,用来添加成功或失败的回调 then(onFulfilled, onRejected) { // onFulfilled 和 onRejected 都是可选参数 onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (value) => value; onRejected = typeof onRejected === 'function' ? onRejected : (err) => { throw err; }; if (this.state === 'fulfilled') { // 如果 Promise 已经解决,直接执行成功回调 onFulfilled(this.value); } else if (this.state === 'rejected') { // 如果 Promise 已经拒绝,直接执行失败回调 onRejected(this.reason); } else { // 如果 Promise 还处于 pending 状态,保存回调函数 this.onResolvedCallbacks.push(onFulfilled); this.onRejectedCallbacks.push(onRejected); } // 返回新的 Promise 实现链式调用 return new MyPromise((resolve, reject) => { // 实现链式调用时,处理回调函数的返回值 try { const x = onFulfilled(this.value); resolve(x); // 处理返回值 } catch (e) { reject(e); // 处理错误 } }); } // catch 方法,用来处理失败的回调 catch(onRejected) { return this.then(null, onRejected); } }

关键点解析

  1. constructor:构造函数接受一个 executor 函数,执行时会传入 resolvereject 函数,这两个函数用于修改 Promise 的状态。
  2. statePromise 有一个状态管理,初始状态为 'pending',之后可以变为 'fulfilled''rejected'
  3. then()
    • then() 方法用于添加成功和失败的回调。
    • 如果 Promise 已经是 fulfilledrejectedthen() 会直接调用相应的回调。
    • 如果 Promise 还处于 pending 状态,则将回调函数存入队列(onResolvedCallbacksonRejectedCallbacks),待状态变更时再执行。
    • then() 方法返回一个新的 Promise,允许链式调用。
  4. catch()catch() 方法用于捕获错误,它是 then(null, onRejected) 的别名。

使用示例

const promise = new MyPromise((resolve, reject) => { const success = true; if (success) { resolve('Promise is resolved!'); } else { reject('Promise is rejected!'); } }); promise .then((message) => { console.log(message); // "Promise is resolved!" return 'Next value'; }) .then((nextMessage) => { console.log(nextMessage); // "Next value" }) .catch((err) => { console.error(err); });

说明:

  • MyPromise 中,resolvereject 用于改变 Promise 的状态。如果 Promise 成功,调用 resolve,如果失败,调用 reject
  • then 方法用于处理 Promise 成功或失败的回调。如果 Promise 已经解决(fulfilled)或拒绝(rejected),then 方法会立刻执行回调;如果还在 pending 状态,then 会将回调函数保存起来,待状态改变时执行。
  • catch 方法用于捕获并处理错误。

总结

通过这个简单的自定义 Promise 实现,你可以理解 Promise 的工作机制,包括状态管理、回调队列、链式调用等。在实际开发中,JavaScript 提供的原生 Promise 可以很好地处理异步任务,但通过理解其内部工作原理,你可以更好地应对复杂的异步逻辑,或者在需要时实现更定制化的异步处理方案。

作者:admin
版权声明:
本文采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!
分享到: