手写Promise,面试

手写promise

使用Promise

 const p = new PromiseAsync((resolve, reject) => {
      setTimeout(() => {resolve('success')}, 1000)
      
    }).then(
      (data) => {console.log('1', data)},
      (err) => {console.log('2', err)}
    )

自己实现Promise.js

// 三个状态:PENDING、FULFILLED、REJECTED
const PENDING = 'PENDING';
const FULFILLED = 'FULFILLED';
const REJECTED = 'REJECTED';

/**
 * 执行顺序是:
 * 1. 初始化 constructor: 
 *          this.status = PENDING, 
 *          this.value
 *          this.reason
 *          resolve
 *          reject
 * 2. 执行new Promise(executor)传入的回调函数 executor
 * 3. 如果executor内是个异步函数
 * 4. 执行then函数,判断如果状态还是pending,将异步回调函数保存到onResolvedCb数组
 * 5. 异步回调执行时,执行resolve() 将pending状态改为fulfilled,然后遍历执行onResolvedCb内的函数
 * 
 * reject同then
 */
class PromiseAsync {
  constructor(executor) {
    // 默认状态为 PENDING
    this.status = PENDING;
    // 存放成功状态的值,默认为 undefined
    this.value = undefined;
    // 存放失败状态的值,默认为 undefined
    this.reason = undefined;

    this.onResolvedCb = [] // 存放成功的回调
    this.onRejectedCb = [] // 存放失败的回调

    // 调用此方法就是成功
    let resolve = (value) => {
      // 状态为 PENDING 时才可以更新状态,防止 executor 中调用了两次 resovle/reject 方法
      if(this.status ===  PENDING) {
        this.status = FULFILLED;
        this.value = value;
        // 依次将对应的函数执行
        this.onResolvedCb.forEach(fn=>fn());
      }
    } 

    // 调用此方法就是失败
    let reject = (reason) => {
      // 状态为 PENDING 时才可以更新状态,防止 executor 中调用了两次 resovle/reject 方法
      if(this.status ===  PENDING) {
        this.status = REJECTED;
        this.reason = reason;
        // 依次将对应的函数执行
        this.onRejectedCb.forEach(fn=>fn());
      }
    }

    try {
      // 立即执行,将 resolve 和 reject 函数传给使用者  
      executor(resolve,reject)
    } catch (error) {
      // 发生异常时执行失败逻辑
      reject(error)
    }
  }

  // 包含一个 then 方法,并接收两个参数 onFulfilled、onRejected
  then(onFulfilled, onRejected) {
    if (this.status === FULFILLED) {
      onFulfilled(this.value)
    }

    if (this.status === REJECTED) {
      onRejected(this.reason)
    }

    if(this.status === PENDING){
      this.onResolvedCb.push(() => {
        onFulfilled(this.value)
      })

      this.onRejectedCb.push(() => {
        onRejected(this.raason)
      })
  }
}
}

说明:

从调用自定义promise的执行过程

  1. 初始化 constructor:
    this.status = PENDING,
    this.value
    this.reason
    resolve
    reject
  2. 执行new Promise(executor)传入的回调函数 executor()
  3. 如果executor内是个异步函数
  4. 执行then函数,判断如果状态还是pending,将异步回调函数保存到onResolvedCb数组
  5. 异步回调执行时,执行resolve() 将pending状态改为fulfilled,然后遍历执行onResolvedCb内的函数

reject实行过程同then的过程
参考
面试官:你能手写一个 Promise 吗

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝with黑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值