手写一个符合Promises/A+规范的Promise_javascript技巧

实现一个符合 Promises/A+ 规范的 Promise 需遵循状态不可变、异步执行、链式调用等规则,核心包括三种状态(pending、fulfilled、rejected)、then 方法返回新 Promise、resolvePromise 处理返回值、catch 和 finally 的语法糖实现,以及静态 resolve 和 reject 方法,完整覆盖规范关键机制。

手写一个符合promises/a+规范的promise_javascript技巧

实现一个符合 Promises/A+ 规范的 Promise 并不只是写个简单的异步容器,而是要严格遵循状态机制、异步解析和链式调用等核心规则。下面是一个精简但完全符合 Promises/A+ 规范核心逻辑的手写 Promise 实现,包含关键特性:状态管理、then 链式调用、值穿透、错误捕获以及异步执行。

Promise 的三种状态

Promise 有三个状态:

pending:初始状态,未完成也未拒绝 fulfilled:操作成功完成 rejected:操作失败

状态一旦从 pending 变为 fulfilled 或 rejected,就不能再改变。

基本结构与状态控制

function MyPromise(executor) {  this.state = 'pending';  this.value = undefined;  this.reason = undefined;  this.onFulfilledCallbacks = [];  this.onRejectedCallbacks = [];  const resolve = (value) => {    if (this.state === 'pending') {      this.state = 'fulfilled';      this.value = value;      this.onFulfilledCallbacks.forEach(fn => fn());    }  };  const reject = (reason) => {    if (this.state === 'pending') {      this.state = 'rejected';      this.reason = reason;      this.onRejectedCallbacks.forEach(fn => fn());    }  };  try {    executor(resolve, reject);  } catch (error) {    reject(error);  }}

构造函数接收一个执行器函数(executor),立即执行,并传入 resolve 和 reject 函数。通过闭包维护状态和回调队列。

立即学习“Java免费学习笔记(深入)”;

实现 then 方法

then 方法是 Promise 的核心,必须返回一个新的 Promise,以支持链式调用。

MyPromise.prototype.then = function(onFulfilled, onRejected) {  // 处理透传值,默认函数  onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val;  onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err; };  const promise2 = new MyPromise((resolve, reject) => {    if (this.state === 'fulfilled') {      setTimeout(() => {        try {          const x = onFulfilled(this.value);          resolvePromise(promise2, x, resolve, reject);        } catch (e) {          reject(e);        }      }, 0);    }    if (this.state === 'rejected') {      setTimeout(() => {        try {          const x = onRejected(this.reason);          resolvePromise(promise2, x, resolve, reject);        } catch (e) {          reject(e);        }      }, 0);    }    if (this.state === 'pending') {      this.onFulfilledCallbacks.push(() => {        setTimeout(() => {          try {            const x = onFulfilled(this.value);            resolvePromise(promise2, x, resolve, reject);          } catch (e) {            reject(e);          }        }, 0);      });      this.onRejectedCallbacks.push(() => {        setTimeout(() => {          try {            const x = onRejected(this.reason);            resolvePromise(promise2, x, resolve, reject);          } catch (e) {            reject(e);          }        }, 0);      });    }  });  return promise2;};

注意使用 setTimeout 模拟异步微任务(实际规范中应使用 queueMicrotask,但 setTimeout 在浏览器中可模拟异步行为)。

处理返回值 resolvePromise

这个函数决定如何处理 then 回调的返回值 x,是 Promises/A+ 最复杂的一部分。

function resolvePromise(promise2, x, resolve, reject) {  if (promise2 === x) {    return reject(new TypeError('Chaining cycle detected'));  }  let called = false;  if (x != null && (typeof x === 'object' || typeof x === 'function')) {    try {      const then = x.then;      if (typeof then === 'function') {        then.call(x, y => {          if (called) return;          called = true;          resolvePromise(promise2, y, resolve, reject);        }, r => {          if (called) return;          called = true;          reject(r);        });      } else {        resolve(x);      }    } catch (e) {      if (called) return;      called = true;      reject(e);    }  } else {    resolve(x);  }}

该函数判断 x 是否为 Promise 或类 Promise 对象(有 then 方法),递归解析直到得到最终值。

补充方法:catch 和 finally

catch 是 then 的语法糖,只处理错误。

MyPromise.prototype.catch = function(onRejected) {  return this.then(null, onRejected);};MyPromise.prototype.finally = function(callback) {  return this.then(    value => MyPromise.resolve(callback()).then(() => value),    reason => MyPromise.resolve(callback()).then(() => { throw reason; })  );};

finally 不影响结果值,无论成功或失败都会执行 callback。

静态方法:resolve 和 reject

MyPromise.resolve = function(value) {  return new MyPromise(resolve => resolve(value));};MyPromise.reject = function(reason) {  return new MyPromise((_, reject) => reject(reason));};

基本上就这些。这个手写 Promise 覆盖了 Promises/A+ 的主要规范点:状态不可逆、then 返回新 Promise、异步执行、错误捕获、链式解析。虽然没有覆盖所有边界测试,但已足够理解其核心机制。在真实项目中推荐使用原生 Promise,但在面试或学习时,这种实现能深刻掌握异步编程原理。

以上就是手写一个符合Promises/A+规范的Promise_javascript技巧的详细内容,更多请关注php中文网其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1533903.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
JavaScript 表单操作:获取表单数据与表单验证
上一篇 2025年12月21日 01:09:22
理解JavaScript中的微任务与宏任务_javascript事件循环
下一篇 2025年12月21日 01:09:39

相关推荐

发表回复

登录后才能评论
关注微信