基础-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成功。

相关推荐
汪子熙20 分钟前
Angular 服务器端应用 ng-state tag 的作用介绍
前端·javascript·angular.js
Envyᥫᩣ29 分钟前
《ASP.NET Web Forms 实现视频点赞功能的完整示例》
前端·asp.net·音视频·视频点赞
Мартин.4 小时前
[Meachines] [Easy] Sea WonderCMS-XSS-RCE+System Monitor 命令注入
前端·xss
昨天;明天。今天。6 小时前
案例-表白墙简单实现
前端·javascript·css
数云界6 小时前
如何在 DAX 中计算多个周期的移动平均线
java·服务器·前端
风清扬_jd6 小时前
Chromium 如何定义一个chrome.settingsPrivate接口给前端调用c++
前端·c++·chrome
安冬的码畜日常6 小时前
【玩转 JS 函数式编程_006】2.2 小试牛刀:用函数式编程(FP)实现事件只触发一次
开发语言·前端·javascript·函数式编程·tdd·fp·jasmine
ChinaDragonDreamer6 小时前
Vite:为什么选 Vite
前端
小御姐@stella6 小时前
Vue 之组件插槽Slot用法(组件间通信一种方式)
前端·javascript·vue.js
GISer_Jing6 小时前
【React】增量传输与渲染
前端·javascript·面试