手动实现promise

  • 创建promise的基础框架
function MyPromise(executor) {

  function resolve(value) {

  }

  function reject(reason) {
    
  }

  try {
   // executor为new promise时传入的函数,executor的两个参数分别为成功回调函数和失败的回调
    executor(resolve, reject)
  } catch (reason) {
    reject(reason)
  }
}

使用:

let promise = new MyPromise(function(resolve, reject) {
  resolve(123);
})
  • 添加状态机

promise是一个状态机,只要promise执行就进入pending状态,然后是成功状态的话就是fulfilled,失败状态的就是rejected。也就是pending -> fulfilled 或 pending -> rejected,并且状态是不可逆的,一旦转变就不会再变了

const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
function MyPromise(executor) {
  let self = this;
  self.state = PENDING;


  function resolve(value) {
    if (self.state === PENDING) {
      self.state = FULFILLED;
    }
  }

  function reject(reason) {
    if (self.state === PENDING) {
      self.state = REJECTED;
    }
  }

  try {
    executor(resolve, reject);
  } catch (reason) {
    reject(reason);
  }
}
  • 添加状态后还没有结束,发现promise都有then方法,那么我们来添加一下
// 添加then方法后,我们的构造函数也需要改造一下
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';

function MyPromise(executor) {
  let self = this;

  // 状态机初始状态
  self.state = PENDING
  // promise成功后吐出的数据
  self.value = null
  // promise失败后吐出的数据
  self.reason = null

  function resolve(value) {
    if (self.state === PENDING) {
      self.state = FULFILLED
      self.value = value
    }
  }

  function reject(reason) {
    if (self.state === PENDING) {
      self.state = REJECTED
      self.reason = reason
    }
  }

  try {
    executor(resolve, reject)
  } catch (reason) {
    reject(reason)
  }
}

// 添加then方法,因为我们调用then是直接使用类来调用,并不是实例,所以直接定义在原型上
MyPromise.prototype.then = function(onFuifilled, onRejected) {
  let self = this

  if (self.state === FULFILLED) {
    onFuifilled(self.value)
  }

  if (self.state === REJECTED) {
    onRejected(self.reason)
  }
}

我们都知道then方法有两个参数, 分别是成功的回调和失败回调,对应上面就是onFulfilled,onRejected

使用一下:


let promise = new MyPromise(function(resolve, reject) {
  resolve(1111)
})
promise.then(res => {
  console.log(res)
})

我们发现,同步函数这么执行时没有问题,但是我们添加了异步函数比如说setTimeout后就不正常了,比如我们像这样执行

let MyPromise1 = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    resolve(1111)
  })})
MyPromise1.then((res) => {
  console.log(res)
})

1.目前的代码在调用then()方法时,state仍是pending状态,当timer到时候调用resolve()把state修改为fulfilled状态,但是onFulfilled()函数已经没有时机调用了;
2.也就是代码先执行了then方法,然后才去执行的构造函数中的reslove方法

  • 实现异步调用resolve
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejectd'

function MyPromise (executor) {
  let self = this
  
  self.state = PENDING
  self.value = null
  self.reason = null
  
  // 添加这两个数组来存放未来要执行的方法
  self.onFulfilledCallBacks = []
  self.onRejectedCallBacks = []

  function resolve (value) {
    if (self.state === PENDING) {
      self.state = FULFILLED
      self.value = value
      self.onFulfilledCallBacks.forEach(fn => {
        fn()
      })
    }
  }
  function reject (reason) {
    if (self.state === PENDING) {
      self.state = REJECTED
      self.reason = reason
      self.onRejectedCallBacks.forEach(fn => {
        fn()
      })
    }
  }
  try {
    executor(resolve, reject)
  } catch {
    reject(reason)
  }
}

MyPromise.prototype.then = function (onFulfilled, onRejected) {
  let self = this
  // 通过以上例子,我们知道异步先执行的then,并且这时state是PENDING,将未来要执行的方法放在对应的数组中
  // 然后执行完then后,已经存放未来要执行的方法,然后再执行reslove方法时只需要一个个拿出来去执行即可
  if (self.state === PENDING) {
    self.onFulfilledCallBacks.push(() => {
      onFulfilled(self.value)
    })
    self.onRejectedCallBacks.push(() => {
      onRejected(self.reason)
    })
  }
  if (self.state === FULFILLED) {
    onFulfilled(self.value)
  }
  if (self.state === REJECTED) {
    onRejected(self.reason)
  }
}

使用:

let MyPromise1 = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    resolve(2222)
  })
})
MyPromise1.then((res) => {
  console.log(res)
})

以上简单完成了promise,还有很多没有实现,后续再来跟大家分享

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值