首页 > 其他分享 >手动实现promise核心

手动实现promise核心

时间:2023-10-12 21:44:37浏览次数:32  
标签:resolve 函数 核心 手动 state ._ promise reject Promise

了解Promise

Promise 构造函数是 JavaScript 中用于创建 Promise 对象的内置构造函数。

Promise 构造函数接受一个函数作为参数,该函数是同步的并且会被立即执行,所以我们称之为起始函数。起始函数包含两个参数 resolve 和 reject,分别表示 Promise 成功和失败的状态。

起始函数执行成功时,它应该调用 resolve 函数并传递成功的结果。当起始函数执行失败时,它应该调用 reject 函数并传递失败的原因。

Promise 构造函数返回一个 Promise 对象,该对象具有以下几个方法:

  • then:用于处理 Promise 成功状态的回调函数。
  • catch:用于处理 Promise 失败状态的回调函数。
  • finally:无论 Promise 是成功还是失败,都会执行的回调函数。

实现一个能把函数放入微队列执行的函数

  • 可以利用MutationObserver的特性把函数放入微队列中执行
  • MutationObserver是一个观察器,使用的时候需要传入一个函数,当它观察到元素发生变化时会把传入的函数放入微队列中执行
// 实现把函数放入微队列执行
function runMicroTask(fn) {
  // 检测当前环境是node环境还是浏览器环境
  // none环境中有process对象,process.nextTick可以直接把函数放入微队列中执行
  if (typeof process !== 'undefined' && typeof process.nextTick === 'function') {
    return process.nextTick(fn)
  } else if (typeof MutationObserver === 'function') {
    const ob = new MutationObserver(fn)
    const textNode = document.createTextNode('1')
    ob.observe(textNode, {
      characterData: true
    })
    textNode.data = 2
  }
}

完整实现代码

function runMicroTask(fn) {
  if (typeof process !== 'undefined' && typeof process.nextTick === 'function') {
    return process.nextTick(fn)
  } else if (typeof MutationObserver === 'function') {
    const ob = new MutationObserver(fn)
    const textNode = document.createTextNode('1')
    ob.observe(textNode, {
      characterData: true
    })
    textNode.data = 2
  }
}

// 检测一个对象是否为promise对象
function isPromiseLike(obj) {
  return !!(obj && typeof obj === 'object' && typeof obj.then === 'function')
}

const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
class MyPromise {

  /**
   * 
   * @param {Function} executor 任务执行器,立即执行
   */
  constructor(executor) {
    this._state = PENDING
    this._value = void 0
    this._handlers = []
    try {
      executor(this._resolve.bind(this), this._reject.bind(this))
    } catch (error) {
      this._reject(error)
    }
  }

  _resolve(data) {
    this._changeState(FULFILLED, data)
  }

  _reject(reason) {
    this._changeState(REJECTED, reason)
  }

  _changeState(newState, data) {
    if (this._state !== PENDING) return
    this._state = newState
    this._value = data
    this._runHandlers()
  }


  /**
   * 
   * @param {Function} executor  处理函数
   * @param {String} state   执行处理函数的状态
   * @param {Function} resolve  
   * @param {Function} reject 
   */
  _pushHandlers(executor, state, resolve, reject) {
    this._handlers.push({
      executor,
      state,
      resolve,
      reject
    })
  }

  _runHandlers() {
    if (this._state === PENDING) return
    while (this._handlers[0]) {
      const handle = this._handlers[0]
      this._runOneHandler(handle)
      this._handlers.shift()
    }
  }


  /**
   * 
   * @param {Object} handle 
   */
  _runOneHandler({ executor, state, resolve, reject }) {
    runMicroTask(() => {
      if (this._state !== state) return
      if (typeof executor !== 'function') {
        this._state === FULFILLED
          ? resolve(this._value)
          : reject(this._value)
        return
      }

      try {
        const result = executor(this._value)
        if (isPromiseLike(result)) {
          result.then(resolve, reject)
        }
        resolve(result)
      } catch (error) {
        reject(error)
      }
    })
  }

  /**
   * 
   * @param {Function} onFulfilled 
   * @param {Function} onRejected 
   */
  then(onFulfilled, onRejected) {
    return new MyPromise((resolve, reject) => {
      this._pushHandlers(onFulfilled, FULFILLED, resolve, reject)
      this._pushHandlers(onRejected, REJECTED, resolve, reject)
    })
  }
}

标签:resolve,函数,核心,手动,state,._,promise,reject,Promise
From: https://www.cnblogs.com/blender-su/p/17760657.html

相关文章

  • 动手动脑
    1.  实际操作了一下,发现确实super基类构造法只能在子类构造法前面。放在后面会报错。2. 如果父类的构造方法调用了子类的方法或使用了子类的属性,那么在父类构造方法执行时,子类可能还没有被完全初始化,这将导致运行时错误。因此,不能反过来调用父类的构造方法。必须在子类......
  • 杭州亚运会实现核心系统100%上云、云上转播7200+小时
    杭州亚运会实现核心系统100%上云。10月8日晚,杭州亚运会圆满闭幕。作为史上首届“云上亚运”,杭州亚运会创造了历史。杭州亚运会实现了核心系统100%上云,并借助后台云算力、云存储等云技术保障,建设一系列各层级、各场馆数字指挥平台,实现全面感知、高效指挥。同时,首次实现云上转播,......
  • fastapi手动添加swagger文档描述
    fastapi手动添加swagger文档描述"""在正常开发过程中,fastapi会自动地将正确响应(status=200)和输入校验失败响应(status=422)添加到文档中.当有自定义的响应描述添加到文档中时,就需要我们手动添加到路径函数的:responses参数中.用户可以按照openapi的语法,将响应的描述信息添加......
  • MTK8183/MT8183安卓4G核心板_联发科安卓手机开发板主板方案定制
    MediaTek MT8183整合先进功能和AI的主流Chromebook平台MTK8183又称为MediaTekKompanio500,是一款支持强大功能的Chromebook平台,结合多种高功能硬件于单一高效能芯片。支持连接选项包括Wi-Fi、蓝芽和GNSS,外围设备可选择连接USB3(5Gbps)和SDIO,以协助品牌厂商能以各种效能水......
  • pip 手动安装 jieba包 | [babyllama2-chinese]
    在复现babyllama2-chinese项目时,jieba无论是用pip还是conda进行安装都会报错,遂尝试手动安装,步骤如下:先参考一篇博客以及我自己的博客:conda、pip从本地安装包我直接进入pip官网:https://pypi.org搜索jieba包这里需要注意,如果需要下载历史版本,请点击Releasehisto......
  • 关于微信小程序VM22:2 (in promise) MiniProgramError {“errMsg“:“hideLoading:fai
    参考地址:https://blog.csdn.net/qq_41227106/article/details/108465104 出现错误的原因如下1、是微信小程序2、把请求接口统一封装,开始请求接口时showLoading,请求接口后hideLoading3、一个页面同时请求多个接口,由于请求是异步的,很有可能上一个开启了showLoading还没请求完......
  • MT8390安卓核心板参数_联发科Genio 700智能模组
    MT8390安卓核心板是一款功能强大且高度集成的平台,专为广泛的人工智能(AI)和物联网(IoT)应用案例而设计。它具备高性能边缘处理、先进的多媒体和连接能力、多个高分辨率摄像头、连接的触摸屏显示以及多任务高级操作系统的使用。MT8390安卓核心板采用高性能的八核应用处理器,......
  • kubelet证书手动续签
    查看证书是否过期opensslx509-in/var/lib/kubelet/pki/kubelet.crt-noout-dates模拟证书过期#dateThuNov700:05:17CST2021#date-s"2022-10-07"FriNov700:00:00CST2022#dateFriNov700:00:02CST2022备份旧证书cp/var/lib/kubelet/pki/kube......
  • top中查看多核心的CPU
    某项目中,有一进程占用CPU是110%,排查进程是单一还是多核心都占用这么高运行top命令再按下数字1就显示多核心的占用来源:https://blog.csdn.net/m0_71252134/article/details/125634987......
  • es6之Promise对象
    1.简介1、是一种异步编程的解决方案,主要是解决异步回调的问题2、所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise是一个对象,从它可以获取异步操作的消息。Promise提供统一的API,各种异步操作都可以用同......