Promise——深度理解实现原理

105 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第4天,点击查看活动详情

本篇文章主要在于深度探究 Promise 的实现原理

1. Promise 基本结构

new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('FULFILLED')
  }, 1000)
})

构造函数Promise必须接受一个函数作为参数,我们称该函数为handlehandle又包含resolvereject两个参数,它们是两个函数。

2. Promise 状态和值

Promise 对象存在以下三种状态:

  • Pending(进行中)
  • Fulfilled(已成功)
  • Rejected(已失败)

状态只能由 Pending 变为 Fulfilled 或由 Pending 变为 Rejected ,且状态改变之后不会在发生变化,会一直保持这个状态。

Promise的值是指状态改变时传递给回调函数的值

一个函数包含 resolve 和 reject 两个参数,它们是两个函数,可以用于改变 Promise 的状态和传入 Promise 的值

  setTimeout(() => {
    resolve('FULFILLED')
  }, 1000)
})

这里 resolve 传入的 "FULFILLED" 就是 Promise 的值

resolve 和 reject

  • resolve : 将Promise对象的状态从 Pending(进行中) 变为 Fulfilled(已成功)

  • reject : 将Promise对象的状态从 Pending(进行中) 变为 Rejected(已失败)

  • resolvereject 都可以传入任意类型的值作为实参,表示 Promise 对象成功(Fulfilled)和失败(Rejected)的值 了解了 Promise 的状态和值,接下来,我们为 MyPromise 添加状态属性和值

首先定义三个常量,用于标记Promise对象的三种状态

// 定义Promise的三种状态常量
const PENDING = 'PENDING'
const FULFILLED = 'FULFILLED'
const REJECTED = 'REJECTED'

再为 MyPromise 添加状态和值,并添加状态改变的执行逻辑

  constructor (handle) {
    if (!isFunction(handle)) {
      throw new Error('MyPromise must accept a function as a parameter')
    }
    // 添加状态
    this._status = PENDING
    // 添加状态
    this._value = undefined
    // 执行handle
    try {
      handle(this._resolve.bind(this), this._reject.bind(this)) 
    } catch (err) {
      this._reject(err)
    }
  }
  // 添加resovle时执行的函数
  _resolve (val) {
    if (this._status !== PENDING) return
    this._status = FULFILLED
    this._value = val
  }
  // 添加reject时执行的函数
  _reject (err) { 
    if (this._status !== PENDING) return
    this._status = REJECTED
    this._value = err
  }
}

这样就实现了 Promise 状态和值的改变。下面说一说 Promise 的核心: then 方法

3. Promise 的 then 方法

then()方法用于指定当前实例状态发生改变时的回调函数。它返回一个新的Promise实例。

语法:

Promise.prototype.then(onFulfilled, onRejected);

参数:

onFulfilled:当前实例变成fulfilled状态时,该参数作为回调函数被调用。

onRejected:当前实例变成reject状态时,该参数作为回调函数被调用。

返回值:

一个新的Promise实例。

注意:

onFulfilled将接收一个参数,参数值由当前Promise实例内部的resolve()方法传值决定;onRejected将接收一个参数,参数值由当前Promise实例内部的reject()方法传值决定。