按照 Promise/A+ 手写Promise,通过promises-aplus-tests的全部872个测试用例

链接:https://juejin.cn/post/6910500073314975758

本文主要讲述如何根据 Promises/A+ 规范,一步步手写一个 Promise 的 polyfill,代码中会配上对应的规范解释。

1. 定义需要的常量和工具方法

// 1. 定义表示promsie状态的常量
const PENDING_STATE = "pending";
const FULFILLED_STATE = "fulfilled";
const REJECTED_STATE = "rejected";
// 2. 定义可复用的工具方法
const isFunction = function(fun) {
  return typeof fun === "function";
};
const isObject = function(value) {
  return value && typeof value === "object";
};
复制代码

2. Promsie 构造函数

Promsie 构造函数内部,主要做 5 件事儿:

function Promise(fun) {
  // 1. 基本的判断: 判断 Promsie 构造函数是否是通过 new 调用,以及调用时传入的参数 fn 是否是一个函数;
  // 2. 定义 promise 实例的基本属性;
  // 3. 定义 resolve 方法;
  // 4. 定义 reject 方法;
  // 5. 执行 fun 函数;
}
复制代码

2.1 基本的判断

function Promise(fun) {
  // 1. 基本的判断
  // 1.1 判断是否是通过new调用
  if (!this || this.constructor !== Promise) {
    throw new TypeError("Promise must be called with new");
  }
  // 1.2 判断参数fun是否是一个函数
  if (!isFunction(fun)) {
    throw new TypeError("Promise constructor's argument must be a function");
  }
  // ...
}
复制代码

2.2 定义 promise 实例的基本属性

function Promise(fun) {
  // ...
  // 2. 定义基本属性
  this.state = PENDING_STATE; // promise实例的状态
  this.value = void 0; // promise的决议值
  // Promises/A+:2.2.6 一个promise实例,可能会调用多次then函数,所以需要一个数组保存then中注册的回调并记录其调用顺序
  this.onFulfilledCallbacks = []; // 保存完成回调
  this.onRejectedCallbacks = []; // 保存拒绝回调
  // ...
}
复制代码

2.3 定义 resolve 方法

function Promise(fun) {
  // ...
  // 3. 定义resolve方法
  const resolve = (value) => {
    resolutionProcedure(this, value);
  };
  // 主要执行Promise的决议逻辑
  const resolutionProcedure = function(promise, x) {
    // ...
  };
  // ...
}
复制代码
2.3.1 Promise 的决议逻辑

Promise 的决议逻辑是 Promise 的一大重点,也是一大难点,把这个逻辑搞清楚了,手写 Promise 就成功一半了。Promise 的决议函数 resolutionProcedure 接收 2 个参数,第一个参数是需要决议的promise实例,第二个参数是决议值,即调用resolve(x)的时候传进去的参数x。Promise 的决议程序主要做了 4 件事:

  1. 判断 x 和 promise 是否指向同一个对象;

  2. 判断 x 是否是一个 promise 实例;

  3. 判断是否是 thenable;

  4. x 为其他 js 基础值,且未决议,则直接决议;

function Promise(fun) {
  // ...
  const resolutionProcedure = function(promise, x) {
    // 3.1 判断 x 和 promise 是否指向同一个对象
    // Promises/A+:2.3.1 如果promise和x引用相同的对象,则抛出一个TypeError为原因拒绝promise。
    if (x === promise) {
      return reject(new TypeError("Promise can not resolved with it seft
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值