手写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

相关推荐
浮幻云月2 小时前
让 Vue 动画如德芙般丝滑!这个 FLIP 动画组件绝了!
前端·javascript
吃饺子不吃馅2 小时前
揭秘 X6 核心概念:Graph、Node、Edge 与 View
前端·javascript·svg
qwy7152292581632 小时前
Vue中的Provide/Inject如何实现动态数据
前端·javascript·vue.js
艾小码2 小时前
告别重复代码!React自定义Hook让逻辑复用如此简单
前端·javascript·react.js
yoyoma2 小时前
react-infinite-scroll-component 使用注意事项
前端
快乐是一切2 小时前
PDF文件的交叉引用表(xref)与 trailer
前端
Never_Satisfied2 小时前
在JavaScript / HTML中,让<audio>元素中的多个<source>标签连续播放
开发语言·javascript·html
emma羊羊2 小时前
【CSRF】防御
前端·网络安全·csrf
Paddy哥2 小时前
html调起exe程序
前端·html