JS——手写Promise

本文深入探讨Promise的异步执行原理,通过详细步骤介绍如何手写Promise构造函数、then()方法和catch()方法。理解Promise的状态变迁、回调函数的处理以及链式调用的实现是本文的重点。
摘要由CSDN通过智能技术生成


另一篇文章: JS——Promise题目篇幅过长,这篇需要了解东西也多,因此分离出来。

前言

深入了解过 Promise 的人都知道,Promise 所说的异步执行,只是将 Promise 构造函数中 resolve,reject 方法和注册的 callback 转化为 eventLoop的 microtask/Promise Job,并放到 Event Loop 队列中等待执行,也就是 Javascript 单线程中的“异步执行”。
(microtask其实就是微任务)

Promise的大体框架

promise有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)

Promise的大体框架:
1、Promise构造函数:Promise(excutor) { }
excutor函数:同步执行 (resolve,reject) => { }
resolve函数:内部定义成功时我们调用的函数 value =>{ }
reject函数:内部定义失败时我们调用的函数 reason => { }

2、Promise.propotype.then方法:(onFulfilled, onRejected) => { }
onFulfilled函数:成功的回调函数 (value) => { }
onRejected函数:失败的回调函数 (reason) => { }
说明:then返回一个新的Promise。

3、Promise.prototype.catch方法:(onRejected) => { }
onRejeted函数:return this.then(null, onRejected),其实是.then()的简写

// 1、Promise构造函数
function Promise(excutor) {
  // resolve(value) { }
  function resolve(value) {  }
  // reject(reason) { }
  function reject(reason) {  }
  // excutor(resolve,reject)
  try {
    excutor(resolve, reject)
  } catch (err) {
    reject(err)
  }
}
// 2、Promise.propotype.then()
Promise.prototype.then = function (onFulfilled, onRejected) {
  let self = this
  if (self.status === 'fulfilled') {
    return new Promise((resolve, reject) => {
      try {
        ...
      } catch (err) {
        reject(err)
      }
    })
  }
  if (self.status === 'rejected') {
    return new Promise((resolve, reject) => {
      try {
        ...
      } catch (err) {
        reject(err)
      }
    })
  }
  if (self.status === 'pending') {
    return new Promise((resolve, reject) => {
      ...
    })
  }
}
// 3、Promise.prototype.catch()
Promise.prototype.catch = function(onRejected) {
  return this.then(null, onRejected)
}

Promise构造函数实现

1、定义一个常量用来存this的指向。let self = this
2、定义一个状态属性 status、定义两个用来存数据的属性、定义两个用来缓存回调函数 callbacks。状态 self.status = 'pending'、'fulfilled'、'rejected' 存数据 self.value、self.reason 缓存回调函数 self.onFulfilledCallbacks = [] self.onRejectedCallbacks = []
3、定义两个用于改变Promise状态的函数 resolve 和 reject
4、函数里面:首先判断当前状态是不是 ‘pending’ 状态,如果是则直接返回,因为在promise中状态只能改变一次。其次改变当前的状态为对应的状态,再存入当前的数据。最后判断如果有待执行的callback函数,立即异步执行回调函数onResolved()/onRejected()
5、try catch 用来捕获异常

function Promise(excutor) {
  let self = this
  self.status = 'pending'
  self.value = null
  self.reason = null
  self.onFulfilledCallbacks = []
  self.onRejectedCallbacks = []

  function resolve(value) {
    if (self.status === 'pending') {
      self.value = value
      self.status = 'fulfilled'
      self.onFulfilledCallbacks.forEach(item => item())
    }
  }

  function reject(reason) {
    if (self.status === 'pending') {
      self.reason = reason
      self.status = 'rejected'
      self.onRejectedCallbacks.forEach(item => item())
    }
  }
  try {
    excutor(resolve, reject)
  } catch (err) {
    reject(err)
  }
}

Promise.then()方法和catch()方法的实现

1、判断回调函数的类型:是函数,则继续向下传递;否则直接resolve( )或throw err。
2、定义一个常量,用来获取this的指向 let self = this
3、链式调用,当执行完then后可以继续执行then,其实它的原理就是通过返回一个新的Promise实现的。
then方法接收的两个函数中,可以通过return把值传给下一个步,也可以返回一个新的Promise把值传给下一步,then方法执行的时候有个特点,就是为了保证链式调用,上一次then中不管你是成功还是失败都会把参数作为下一个then中成功时回调的参数

Promise.prototype.then = function (onFulfilled, onRejected) {
  // 判断回调函数的类型
  onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => {resolve(value)}
  onRejected = typeof onRejected === 'function' ? onRejected : reason => {throw err}
  let self = this
  if (self.status === 'fulfilled') {
    return new Promise((resolve, reject) => {
      try {
        let x = onFulfilled(self.value)
        if (x instanceof Promise) {
          x.then(resolve, reject)
        } else {
          resolve(x)
        }
      } catch (err) {
        reject(err)
      }
    })
  }
  if (self.status === 'rejected') {
    return new Promise((resolve, reject) => {
      try {
        let x = onRejected(self.reason)
        if (x instanceof Promise) {
          x.then(resolve, reject)
        } else {
          resolve(x)
        }
      } catch (err) {
        reject(err)
      }
    })
  }
  if (self.status === 'pending') {
    return new Promise((resolve, reject) => {
      self.onFulfilledCallbacks.push(() => {
        let x = onFulfilled(self.value)
        if (x instanceof Promise) {
          x.then(resolve, reject)
        } else {
          resolve(x)
        }
      })
      self.onRejectedCallbacks.push(() => {
        let x = onRejected(self.reason)
        if (x instanceof Promise) {
          x.then(resolve, reject)
        } else {
          resolve(x)
        }
      })
    })
  }
}

Promise.prototype.catch = function(onRejected) {
  return this.then(null, onRejected)
}

完整代码

// 1、Promise构造函数
function Promise(excutor) {
  let self = this
  self.status = 'pending'
  self.value = null
  self.reason = null
  self.onFulfilledCallbacks = []
  self.onRejectedCallbacks = []

  function resolve(value) {
    if (self.status === 'pending') {
      self.value = value
      self.status = 'fulfilled'
      self.onFulfilledCallbacks.forEach(item => item())
    }
  }

  function reject(reason) {
    if (self.status === 'pending') {
      self.reason = reason
      self.status = 'rejected'
      self.onRejectedCallbacks.forEach(item => item())
    }
  }
  try {
    excutor(resolve, reject)
  } catch (err) {
    reject(err)
  }
}
// 2、Promise.prototype.then()
Promise.prototype.then = function (onFulfilled, onRejected) {
  onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => {resolve(value)}
  onRejected = typeof onRejected === 'function' ? onRejected : reason => {throw err}
  let self = this
  if (self.status === 'fulfilled') {
    return new Promise((resolve, reject) => {
      try {
        let x = onFulfilled(self.value)
        if (x instanceof Promise) {
          x.then(resolve, reject)
        } else {
          resolve(x)
        }
      } catch (err) {
        reject(err)
      }
    })
  }
  if (self.status === 'rejected') {
    return new Promise((resolve, reject) => {
      try {
        let x = onRejected(self.reason)
        if (x instanceof Promise) {
          x.then(resolve, reject)
        } else {
          resolve(x)
        }
      } catch (err) {
        reject(err)
      }
    })
  }
  if (self.status === 'pending') {
    return new Promise((resolve, reject) => {
      self.onFulfilledCallbacks.push(() => {
        let x = onFulfilled(self.value)
        if (x instanceof Promise) {
          x.then(resolve, reject)
        } else {
          resolve(x)
        }
      })
      self.onRejectedCallbacks.push(() => {
        let x = onRejected(self.reason)
        if (x instanceof Promise) {
          x.then(resolve, reject)
        } else {
          resolve(x)
        }
      })
    })
  }
}
// 3、Promise.prototype.catch()
Promise.prototype.catch = function(onRejected) {
  return this.then(null, onRejected)
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值