基础-promise的实现过程(3)

这下要搞的东西就有点嗯,不过脑子的感觉,难度蹭的一下就提高了,头疼啊。其实就是考虑then函数到底要做什么。then就是然后的意思嘛,描述起来就是当成功的时候要做什么,当失败的时候要做什么。那这时马上做吗?不一定。

js 复制代码
p.then(
  (value) => {
    console.log("成功的回调函数");
  },
  (reason) => {
    console.log('失败的回调函数');
  }
);

就算是then函数要立刻去执行里面的函数,那是不是一定要放到微队列里边?

如何来产生一个微队列呢?

js 复制代码
function runMicroTask(callback) {
  // node environments
  if (process && process.nextTick) {
    process.nextTick(callback);
  } else if (MutationObserver) {
    const a = document.createElement("span");
    new MutationObserver(callback).observe(a, {
      attributes: true,
    });
    a.innerHTML = 1;
  } else {
    setTimeout(callback, 0);
  }
}

这就算是简单的产生了一个微队列了,node环境通过process.nextTick来执行微队列。浏览器通过MutationObserver来执行微队列。

好了,下面就来实现一下then函数,只能实现个大概啊,毕竟then函数还是很复杂的。在写then函数的时候,思考下它有什么样的参数传入,有什么样的返回值。

看了promise,知道需要两个参数,一个是成功之后要做的事,一个是失败之后要做的事。

js 复制代码
 /**
   * @description: then 成功或失败要做的事 满足 Promise A+ 规范
   * @param {* Function} onFulfilled 成功的回调
   * @param {* Function} onRejected 失败的回调
   * @return {* Object} Object 返回一个新的Promise
   */
  then(onFulfilled, onRejected) {
    return new myPromise((resolve, reject) => {});
  }

then函数不是马上执行,也不是马上把它放到微队列,是要等状态确定了之后才执行。

then函数具体要做的事就是把函数放入一个队列。相当于是一个数组,调用一次then就放入一个函数,但不执行。再调用一次then,再放入一个函数... 等到将来状态确定了之后,再从头到尾依次去执行这些函数。所以我们的myPromise需要一个队列来存放这些函数。那then理解起来就变得简单了,就是把函数放入队列。

js 复制代码
    this._handler = []; //处理函数形成的队列

当调用then的时候,就把函数放进去。但是当所有函数放完了,将来状态改变,从头到尾依次执行函数的时候,并不知道这个函数是成功的还是失败的,所以得给这些函数标记个属性。所以抽离一个函数去做这些标记。

js 复制代码
  /**
   * @description: 向处理队列中添加一个函数,并标记类型
   * @param {Function} excutor 需要存入的函数
   * @param {String} state 该函数什么状态下执行
   * @return {*}
   */
  _pushHandler(excutor, state) {
    this._handler.push({
      excutor,
      state,
    });
  }
  
   /**
   * @description: then 成功或失败要做的事 满足 Promise A+ 规范
   * @param {Function} onFulfilled 成功的回调
   * @param {Function} onRejected 失败的回调
   * @return {Object} Object 返回一个新的Promise
   */
  then(onFulfilled, onRejected) {
    this._pushHandler(onFulfilled, FULFILLED);
    this._pushHandler(onRejected, REJECTED);
    return new myPromise((resolve, reject) => {});
  }

现在then函数返回了一个myPromise,那里面的resolvereject什么时候执行呢?一定是要等将来队列里函数执行的时候再去调用,比如说,

这个函数执行没有问题,那就说明了then返回的那个myPromise是成功的,所以此时调用resolve,同理reject也是一样。

因此,只有当队列里函数执行的时候,才能确定then返回的myPromise是成功的还是失败的。

那如何去获取这个resolvereject呢?

传给队列处理函数,等将来函数执行了,就按条件执行resolvereject

js 复制代码
  /**
   * @description: 向处理队列中添加一个函数,并标记类型
   * @param {Function} excutor 需要存入的函数
   * @param {String} state 该函数什么状态下执行
   * @param {Function} resolve 让then函数返回的 promise 成功
   * @param {Function} reject 让then函数返回的 promise 失败
   * @return {*}
   */
  _pushHandler(excutor, state, resolve, reject) {
    this._handler.push({
      excutor,
      state,
      resolve,
      reject,
    });
  }
  
   /**
   * @description: then 成功或失败要做的事 满足 Promise A+ 规范
   * @param {Function} onFulfilled 成功的回调
   * @param {Function} onRejected 失败的回调
   * @return {Object} Object 返回一个新的Promise
   */
  then(onFulfilled, onRejected) {
    return new myPromise((resolve, reject) => {
      this._pushHandler(onFulfilled, FULFILLED, resolve, reject);
      this._pushHandler(onRejected, REJECTED,resolve, reject);
    });
  }

现在来调用看看。

js 复制代码
p.then(
  function A1() {},
  function A2() {}
);
p.then(
  function B1() {},
  function B2() {}
);

总共传了4个函数,那这4个函数都被放到队列里了。

那等将来这个excutor函数成功执行,那就调用resolve,让then返回的myPromise成功。

相关推荐
灿灿121389 分钟前
CSS 文字浮雕效果:巧用 text-shadow 实现 3D 立体文字
前端·css
烛阴27 分钟前
Babel 完全上手指南:从零开始解锁现代 JavaScript 开发的超能力!
前端·javascript
AntBlack1 小时前
拖了五个月 ,不当韭菜体验版算是正式发布了
前端·后端·python
31535669131 小时前
一个简单的脚本,让pdf开启夜间模式
前端·后端
尘心cx1 小时前
前端-CSS-day1
前端·css
知否技术1 小时前
前端常说的 SCSS是个啥玩意?一篇文章给你讲的明明白白!
前端·scss
CN-Dust1 小时前
[FMZ][JS]第一个回测程序--让时间轴跑起来
javascript
幼儿园技术家1 小时前
Uniapp简易使用canvas绘制分享海报
前端
开开心心就好2 小时前
免费PDF处理软件,支持多种操作
运维·服务器·前端·spring boot·智能手机·pdf·电脑
全宝2 小时前
🎨前端实现文字渐变的三种方式
前端·javascript·css