手写Promise-静态方法reoslve和reject

在前一篇文章中,我们实现了符合Promise A+规范的Promise核心功能。本文将聚焦于两个重要的静态方法:Promise.resolvePromise.reject,带你深入理解它们的实现细节和边界情况处理。

实现Promise.resolve

在MDN规范中,Promise.resolve有四种情况需要处理:

  1. Promise实例:如果参数是一个Promise对象,直接返回该对象
  2. Thenable对象:参数是具有then方法的对象,将其转换为符合规范的Promise
  3. 普通值:参数是普通值,创建已完成的Promise并返回该值
  4. 嵌套Thenable:参数是嵌套的thenable对象,需要深度展平返回单个Promise

之前代码基础上搭建代码基本结构:

js 复制代码
(function () {
  "use strict";
  /* 上面代码省略 */
  var prototype = Promise.prototype;
  
  function definePropertyConfig(object, key, value) {
    Object.defineProperty(object, key, {
      value: value,
      writable: true,
      enumerable: false,
      configurable: true,
    });
  }
  // Promise解析核心算法(复用之前实现)
  var resolvePromise = function (promise, x, resolve, reject) {
    // ... 原有实现,用于处理thenable对象和循环引用
  };

  function checkPromiseInstance(value) {
    if (!(value instanceof Promise)) {
      throw new TypeError(
        "Method Promise.prototype.then called on incompatible receiver #<Promise>"
      );
    }
  }
  definePropertyConfig(Promise, 'resolve', function (value) {
    /* 在此处实现resolve */
  })
  definePropertyConfig(Promise, 'reject', function (value) {
    /* 在此处实现reject */
  })
  /* 下面代码省略 */
  
})();

参数是Promise对象

js 复制代码
const p1 = new Promise((resolve) => {
  resolve(1);
});
const p2 = Promise.resolve(p1);
console.log(p1 === p2); // true

实现代码:

js 复制代码
definePropertyConfig(Promise, 'resolve', function (value) {
  if (value instanceof Promise) {
    return value
  }
});

复用resolvePromise处理其他情况

其他三个情况其实就是对具有then方法的深度解析。在上篇文章中已经编写了Promise的解析代码。在此可以复用。

js 复制代码
  definePropertyConfig(Promise, "resolve", function (value) {
    if (value instanceof Promise) return value;
    return new Promise(function (resolve, reject) {
      const p = new Promise(function () {});
      resolvePromise(p, value, resolve, reject);
    });
  });

边界情况处理

js 复制代码
// 原生Promise代码
var p = Promise.resolve;
p(2) // 此处将会报错

添加防护代码:

js 复制代码
// Promise.resolve方法最顶部添加以下代码:
if (!(this === Promise)) {
  throw new TypeError("PromiseResolve called on non-object");
}

完整的Promise.resolve代码

js 复制代码
definePropertyConfig(Promise, "resolve", function (value) {
  if (!(this === Promise)) {
    throw new TypeError("PromiseResolve called on non-object");
  }
  if (value instanceof Promise) return value;
  return new Promise(function (resolve, reject) {
    // 为了满足resolvePromise函数的参数要求,循环引用检测
    const p = new Promise(function () {});
    resolvePromise(p, value, resolve, reject);
  });
});

实现Promise.reject

Promise.reject的实现相对简单,它总是返回一个已拒绝的Promise:

js 复制代码
definePropertyConfig(Promise, "reject", function (reason) {
  // 与Promise.resolve一样
  if (!(this === Promise)) {
    throw new TypeError("PromiseReject called on non-object");
  }
  return new Promise(function (_, reject) {
    reject(reason);
  });
});

小结

通过手写实现Promise.resolvePromise.reject,我们深入理解了:

  1. 规范一致性:如何确保自定义实现与原生Promise行为完全一致
  2. 递归解析 :通过resolvePromise算法处理复杂的thenable嵌套结构
  3. 防御性编程:通过上下文检查预防常见的错误用法模式
  4. 代码复用:充分利用现有逻辑,避免重复实现复杂算法

这些静态方法不仅是工具函数,更是理解Promise生态系统的关键。它们的实现展示了如何将各种类型的值统一封装为标准的Promise对象,为异步编程提供了坚实的基础。

掌握这些实现原理,不仅有助于深入理解Promise工作机制,也为实现其他复杂的异步模式打下了坚实基础。希望对你有一定帮助。ヾ( ̄▽ ̄)ByeBye

相关推荐
卓伊凡3 分钟前
【03】建立隐私关于等相关页面和内容-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓
前端
笨笨鸟慢慢飞5 分钟前
Vue3后退不刷新,前进刷新
前端
LuckySusu8 分钟前
【vue篇】SSR 深度解析:服务端渲染的“利”与“弊”
前端·vue.js
LuckySusu8 分钟前
【vue篇】SPA 单页面应用:现代 Web 的革命与挑战
前端·vue.js
LuckySusu9 分钟前
【vue篇】Vue 初始化页面闪动(FOUC)问题终极解决方案
前端·vue.js
fruge11 分钟前
从 0 到 1 理解前端工程化:图表化解析核心逻辑
前端
LuckySusu11 分钟前
【vue篇】技术分析:Template 与 JSX 的本质区别与选型指南
前端·vue.js
BestStarLi16 分钟前
个人写码感悟:TailwindCSS不要忽视子选择器
前端
_大学牲18 分钟前
Flutter 之魂 GetX🔥(三)深入掌握依赖管理
前端·flutter
今天头发还在吗24 分钟前
【框架演进】Vue与React的跨越性变革:从Vue2到Vue3,从Class到Hooks
javascript·vue.js·react.js