手写一个简单的promise

// 1. promise三种状态pending fufilled rejected
// 2. promise只能将pending变成fufilled或者pending变成rejected, 状态一但确定无法改变
// 3. promise fufilled执行then中的第一个函数, promise rejected执行then中的第二个函数
// 4. promise有后续处理(then)
// 5. then所对应的promise有三种情况
// (1) 没有对应的后续处理即then中没有对应状态的后续处理回调函数, 则then所对应的promise就吸收之前的promise的状态
// (2) 若后续处理没有执行, 则then所对应的promise处于挂起状态
// (3) 有后续处理
// a 后续处理没有错误, 则返回成功的promise, 值为return的值
// b 后续处理中有错, 则返回失败的promise, 值为失败的原因
// c 后续处理中返回的是一个promise, 则外部的promise吸收return返回的promise的状态

function isPromise(obj) {
return !!(obj && obj.then && typeof obj.then == ‘function’)
}

const pending = ‘PENDING’;
const fufilled = ‘FUFILLED’;
const rejected = ‘REJECTED’;
class MyPromise {
constructor(actuator) {
// 定义初始化状态
this.status = pending;
// 定义状态成功的结果或者是失败的原因
this._value = ‘’;
// 收集then中所有的回调函数
this.callbacks = [];
// actuator 执行器 需要定义两个函数用于改变promise的状态
// 如果执行器执行期间有错误就需要将当前promise的状态变成rejected
try {
actuator(this.resolve.bind(this), this.rejected.bind(this));
} catch (error) {
this.rejected(error);
}
}

updateStatus(status, value) {
// 状态一但确定无法改变
if (this.status != pending) return;

 this.status = status;

 this._value = value;

}

// 将状态改成fufilled
resolve(result) {
this.updateStatus(fufilled, result);
}

// 将状态改成rejected
rejected(reason) {
this.updateStatus(rejected, reason);
}

// then函数返回一个promise, 返回的promise的状态需要根据then方法回调函数的执行结果来处理
// 1.在状态改变时(调用reslve或者rejected)或者then方法执行时 收集起来所有的函数
// 调用异步resolve或者rejected, 此时回调函数已经全部收集, 开启微任务,执行函数
// 调用同步resolve或者rejected, 此时回调函数还没有收集, 也开启微任务,执行函数
// 2.then方法主要就是用来收集fufilledDispose, rejectedDispose, resolve和reject, 保存到一个数组中等到resolve或者
// reject时, 再将数组的执行过程放在微任务里面执行
then(fufilledDispose, rejectedDispose) {
return new MyPromise((resolve, rejected) => {
this.callbacks.push({ status: fufilled, cb: fufilledDispose, resolve, rejected });
this.callbacks.push({ status: ‘REJECTED’, cb: rejectedDispose, resolve, rejected });
// this.execCallbacks();
queueMicrotask(this.execCallbacks.bind(this))
})

}

// 所有then中的回调函数执行
execCallbacks() {

// 如果当前的promise状态是pending, 则终止promise的then的回调函数的处理
if (this.status == pending) return;
// 每次执行完毕之后都需要将当前的对象从callbacks里面删除 原因在于之后还有可能继续调用then,
// 而所有的的回调函数保存在callback里面不删除的话就会导致之后then方法返回的promise的状态有问题
// realExecFns.forEach(({ cb, resolve, rejected }) => {
//   const resullt = cb();
//   resolve(resullt)
// })
while (this.callbacks.length) {
  const { cb, resolve, rejected, status } = this.callbacks[0];
  // realExecFns.splice(0, 1);
  try {
    this.callbacks.splice(0, 1);
    if (status != this.status) {
      continue;
    }
    if (typeof cb != 'function') {
      // 不是函数则当前then返回的promise吸收promise的状态
      if (this.status == fufilled) {
        resolve(this._value);
      } else {
        rejected(this._value);
      }
      continue;
    }

    const result = cb(this._value);
    if (isPromise(result)) {
      // 如果返回的结果是一个promise, 则then返回的promise吸收内部回调函数返回的promise的状态
      // v8源码内部会将result.then(resolve, rejected);也将其包装成一个微任务进行执行
      result.then(resolve, rejected);
      continue;
    }
    resolve(result);
  } catch (error) {
    rejected(error)
  }
}

}

}

const p = new MyPromise((resolve, rejected) => {
// rejected(33333);
// throw new Error(‘33333’)
resolve(22)
});
const p1 = p.then(res => {
// return new MyPromise((resolve, reject) => reject(34))
}, () => {
return new MyPromise((resolve, reject) => {
resolve(34);
}) })
const p2 = p.then()
console.log(‘p1p1p1’,p1)
console.log(‘p2p2p2’,p2)
setTimeout(() => {
console.log('b nbv ', p1)
console.log(‘nbvp2’,p2)
})
// 1.promise有三种状态 一是pending 二是fufilled 三是rejected
// 2.promise只能从pending变成fufilled或者pending变成rejected, 状态一旦确定就无法改变
// 3. promise then返回的promise有三种情况
// (1) then中没有对应的后续处理, 则then返回的promise状态与promise的状态一致
// (2) then中有对应的后续处理, 但是后续处理函数没有执行, 那么then返回的promise处于pending状态
// (3) then中有对应的后续处理, 后续处理函数执行了, 这个时候又有三种情况

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值