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

相关推荐
qq_390161775 分钟前
防抖函数--应用场景及示例
前端·javascript
3345543233 分钟前
element动态表头合并表格
开发语言·javascript·ecmascript
John.liu_Test35 分钟前
js下载excel示例demo
前端·javascript·excel
Yaml41 小时前
智能化健身房管理:Spring Boot与Vue的创新解决方案
前端·spring boot·后端·mysql·vue·健身房管理
PleaSure乐事1 小时前
【React.js】AntDesignPro左侧菜单栏栏目名称不显示的解决方案
前端·javascript·react.js·前端框架·webstorm·antdesignpro
哟哟耶耶1 小时前
js-将JavaScript对象或值转换为JSON字符串 JSON.stringify(this.SelectDataListCourse)
前端·javascript·json
getaxiosluo1 小时前
react jsx基本语法,脚手架,父子传参,refs等详解
前端·vue.js·react.js·前端框架·hook·jsx
理想不理想v1 小时前
vue种ref跟reactive的区别?
前端·javascript·vue.js·webpack·前端框架·node.js·ecmascript
知孤云出岫1 小时前
web 渗透学习指南——初学者防入狱篇
前端·网络安全·渗透·web
贩卖纯净水.1 小时前
Chrome调试工具(查看CSS属性)
前端·chrome