promise执行过程

在看到《前端面试之道》这本小册中关于手写Promise部分,对此部分有比较大的兴趣,于是按照书中的例子加上自己的理解产生了这篇文章,如有理解不到之处,请大佬指出。文章篇幅较长,不喜勿喷

先来实现一个简易版的Promise,代码较长,下面我会一一解释

const PENDING = "pending";
const RESOLVED = "resolved";
const REJECTED = "rejected";
--------------------------------------以上为1.
function MyPromise(fn) {
  const that = this;
  that.state = PENDING;
  that.value = null;
  that.resolvedCallbacks = [];
  that.rejectedCallbacks = [];
  ----------------------------以上为2.1
  // resolve 和 reject 函数
  function resolve(value) {
    // 判断当前状态是否为等待中
    if (that.state === PENDING) {
      that.state = RESOLVED;
      that.value = value;
      that.resolvedCallbacks.map((cb) => cb(that.value));
    }
  }

  function reject(value) {
    // 判断当前状态是否为等待中
    if (that.state === PENDING) {
      that.state = REJECTED;
      that.value = value;
      that.rejectedCallbacks.map((cb) => cb(that.value));
    }
  }
  ------------------------------以上为2.2
  // 执行 fn 函数
  try {
    fn(resolve, reject);
  } catch (e) {
    reject(e);
  }
}
-----------------------------以上为2.3
--------------------------------以上为2
MyPromise.prototype.then = function (onFulfilled, onRejected) {
  const that = this;
  onFulfilled = typeof onFulfilled === "function" ? onFulfilled : (v) => v;
  onRejected =
    typeof onRejected === "function"
      ? onRejected
      : (r) => {
          throw r;
        };
  if (that.state === PENDING) {
    that.resolvedCallbacks.push(onFulfilled);
    that.rejectedCallbacks.push(onRejected);
  }
  if (that.state === RESOLVED) {
    onFulfilled(that.value);
  }
  if (that.state === REJECTED) {
    onRejected(that.value);
  }
};
-----------------------以上为3

以上主要分为3大部分,第二部分中又分为3个小部分

第一部分

  1. 首先我们创建了三个常量用于表示状态,对于经常使用的一些值都应该通过常量来管理,便于开发及后期维护。promise分别有pendingresolvedrejected三种状态

第二部分

  • 2.1部分主要是对promise中需要用到的变量进行初始化
    1.1 在函数体内部首先创建了常量that,因为代码可能会异步执行,用于获取正确的this对象
    1.2 一开始Promise的状态应该是pending
    1.3 value变量用于保存resolve或者reject中传入的值
    1.4 resolvedCallbacksrejectedCallbacks用于保存then中的回调,因为当执行完Promise时状态可能还是等待中,这时候应该把then中的回调保存起来用于状态改变时使用(这个地方第三部分的讲解中会涉及到)
  • 2.2部分主要涉及的是resolvereject函数
    2.1 首先两个函数都得判断当前状态是否为等待中,因为规范规定只有等待态才可以改变状态
    2.2 将当前状态更改为对应状态,并且将传入的值赋值给value
    2.3 遍历回调数组并执行(异步方法)
  • 2.3部分主要是对promise传入的异步方法进行执行,执行函数过程中会遇到错误,需要捕获错误并且执行reject函数

第三部分

  • then中可以传入两个方法,成功执行resolve,失败执行reject
  • 首先判断两个参数是否为函数类型,因为这两个参数是可选参数
  • 当参数不是函数类型时,需要创建一个函数赋值给对应的参数
  • 接下来就是一系列判断状态的逻辑,当状态不是等待态时,就去执行相对应的函数。如果状态是等待态的话,就往回调函数中push函数,比如如下代码就会进入等待态的逻辑
    下面将用一个例子来讲解Promise的执行过程
new MyPromise((resolve, reject) => {
   setTimeout(() => {
     resolve(1)
   }, 1000)
 }).then(value => {
   console.log(value)
 })

在执行上面代码时,过程为:

  • 首先new PromiseMyPromise初始化函数内部参数,Promise传入了一个函数fn
  • 执行fn,传入resolvereject两个方法
  • 执行thenthen接收两个方法,如果不是pending,就去执行响应的函数,现在为等待态,就将console.log放入resolvedCallbacks中,throw r放入rejectedCallbacks
  • 1秒后执行setTimeoutresolve方法,当前状态为pending,将状态修改为resolved,将value修改为resolve(1)中传的值,遍历resolvedCallbacks去执行其中的方法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值