手撕Promise

实现一个promise我个人分为几步

  1. 定义状态和值
  2. 初始化状态和值
  3. 实现resolve和reject方法来改变状态,这里需要注意报错处理和状态确定后就不可改变和this指向问题
  4. 定义任务队列保存下需要执行的函数,在状态改变时去执行
  5. 实现then 执行任务队列,需要判断传入参数不为function 为function和返回一个promise的情况

个人感觉promise源码难点在于状态的透传切换执行成功和失败的方法

      const state = {pending: 0, // 等待fulfilled: 1, // 成功rejected: 2, // 错误}// 创建一个"微任务"const runMicroTask = (fn) => {// 实际上setTimeout并不加入微任务队列,会加入延时队列(w3c已不再推荐使用宏任务微任务来描述)// 这里重点是promise所以暂且就使用setTimeout代替,也可以使用MutationObserver来真正的加入到微任务队列setTimeout(fn, 0)}// 如何判断是promise,按照promise A+ 规范来说 一个对象有then 并且是一个方法 那就是一个promiseconst isPromise = (obj) => {return !!(obj && typeof obj === "object" && typeof obj.then === "function")}class myPromise {constructor (executor) {// 初始化为等待状态this._state = state.pendingthis._value = null// 定义任务队列 在状态改变的时候循环执行里面保存的函数this.handleList = []try {// 创建promise会同步执行一次executor(this.resolve, this.reject)} catch (error) {// 执行出错的处理this.reject(error)}}// 抽离出一个修改状态的方法setState  = (state, value) => {if (state === state.pending) {return }this._state = statethis._value = value// 循环执行任务队列this.runHandleList()}// 成功resolve = (value) => {this.setState(state.fulfilled, value)}// 错误reject = (value) => {this.setState(state.rejected, value)}// then接收两个参数 一个为成功执行的函数一个为失败执行的函数then = (handleFulfilled,handleRejected) => {// 之所以可以链式调用就是因为返回了myPromise类 里面有then方法 return new myPromise((resolve, reject) => {// 传入handleFulfilled 成功处理函数 handleRejected 错误处理函数 // 传入resolve reject来确定当前函数执行后的状态 成功就调用resolve失败执行rejectthis.pushHandleItem({handleFulfilled, handleRejected, resolve, reject})// 这里执行是应为 当前状态可能已经确定了 所以要检查一下this.runHandleList()})}// 把函数加入任务队列pushHandleItem = ({handleFulfilled, handleRejected, resolve, reject}) => {this.handleList.push({handle: handleFulfilled, state: state.fulfilled, resolve, reject})this.handleList.push({handle: handleRejected, state: state.rejected, resolve, reject})}runHandleList = () => {if (this._state === state.pending) {return}this.handleList.forEach(item => {// 放入微任务runMicroTask(this.runOneHandleItem(item))})// 执行完成后清空队列this.handleList = []}runOneHandleItem = ({handle, state: itemState, resolve, reject}) => {// 状态不匹配不做处理if (this._state !== itemState) returnif (typeof handle !== 'function') { // 状态透传itemState === state.fulfilled ? resolve(this._value) : reject(this._value)return}try {const val = handle(this._value)// 判断当前是否返回一个Promise如果是就调用自身的then方法把当前的状态交给返回的Promise处理if (isPromise(val)) {val.then(resolve, reject)} else {// 值透传resolve(val)}} catch (error) {// 失败时的处理reject(error)}}// catch直接调用then即可catch = (onRejected) => {return this.then(undefined, onRejected);};}const pro = new myPromise((resolve, reject) => {resolve('222222222')})pro.then(res => {console.log(res)return new myPromise((resolve, reject) => {reject('3333333333333333')})}).then(res => {console.log(res)}).catch(err => {console.log('err', err)})console.log(pro)

有不足和错误的地方望大佬指出我会及时修正

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/580331.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

FPGA-AMBA协议、APB协议、AHB规范、AXI4协议规范概述及它们之间的关系

FPGA-AMBA协议、APB协议、AHB协议、AXI4协议规范概述 笔记记录,AMBA协议、APB协议、AHB规范、AXI4协议规范概述,只是概述描述,具体详细的协议地址传输、数据传输等内容将在下一章节详细说明。 文章目录 FPGA-AMBA协议…

【目标跟踪】解决多目标跟踪遮挡问题

文章目录 前言一、判定遮挡目标二、扩展目标框三、结论 前言 目标跟踪在发生遮挡时,极其容易发生Id Switch。网上许多算法忽视跟踪遮挡问题,同时网上相关资料也很少。博主为了解决跟踪遮挡,翻阅大量论文。分享其中一篇论文。论文链接:https:…

Everything 搜索

正则表达式Regex 首先需要开启 Everything 工具在(字符串)查找时,对正则表达式功能的支持: 需要在【菜单栏】⇒ 【Search】⇒ 勾选【Enable Regex】 查看Everything 支持的语法:

怎么下载landsat 8影像并在ArcGIS Pro中进行波段组合

Landsat 8(前身为Landsat数据连续性任务,或 LDCM)于2013年2月11日由 Atlas-V火箭从加利福尼亚州范登堡空军基地发射升空,这里为大家介绍一下该数据的下载的方法,希望能对你有所帮助。 注册账号 如果之前已经注册过的…

基于采样的自动驾驶规划算法 - PRM,RRT,RRT*,CL-RRT

本文将讲解PRM,RRT,RRT*自动驾驶规划算法原理,不正之处望读者指正 0 前言 机器人运动规划的基本任务:从开始位置到目标位置的运动 (1)如何躲避构型空间出现的障碍物 (2)如何满足机器…

SkyWalking UI 修改发布Nginx

文章目录 SkyWalking UI修改图标修改路由发布到Nginx添加认证修改路由模式vite.config.ts添加baseNginx配置 SkyWalking UI skywalking-booster-ui下载地址 修改图标 替换 logo.svg 修改路由 router - data - index.ts 发布到Nginx 添加认证 # 安装 yum install -y h…

VMware ESXi常用查看RAID和磁盘信息工具及命令汇总

一、Esxcli 使用 Esxcli 命令可获取有关 vSAN 的信息,以及对您的 vSAN 环境进行故障排除。 可用命令如下: 命令描述esxcli vsan network list确认哪些 VMkernel 适配器可用于 vSAN 通信。esxcli vsan storage list列出由 vSAN 声明的存储磁盘。esxcli…

Pikachu靶场 “Http Header”SQL注入

1. 先在 pikachu 打开 Http Header 注入模块,点击提示 查看登录 账号 和 密码,登陆后去 Burp 中找到登陆的 GET请求 2. 设置payload1 :在 User-Agent最后 输入 查看 数据库名 or updatexml(1,concat(0x7e,database()),0) or 查看 用户名…

随机梯度辨识方法

Matlab 利用随机梯度方法进行辨识的举例,可以结合不同情况进行优化处理(例如需要复现文献中结果) Matlab代码如下: clc;clear;close; format short g; M Stochastic gradient method; sigma 0.5; % Noise standard deviati…

asp.net core 教程

asp.net core 教程 写在前面新建项目Get和PostGETPOST MVC-模型控制视图如何通俗理解MVCMVC架构---文件夹详解Connected ServicesPropertieswwwroot依赖项ControllersModelsViews 代码实例 API模型(前后端分离)前端代码后端代码 文件配置优先级优先级顺序…

YOLOv5改进 | 主干篇 | 利用MobileNetV3替换Backbone(轻量化网络结构)

一、本文介绍 本文给大家带来的改进机制是MobileNetV3,其主要改进思想集中在结合硬件感知的网络架构搜索(NAS)和NetAdapt算法,以优化移动设备CPU上的性能。它采用了新颖的架构设计,包括反转残差结构和线性瓶颈层&…

dev express 15.2图表绘制性能问题(dotnet绘图表)

dev express 15.2 绘制曲线 前端代码 <dxc:ChartControl Grid.Row"1"><dxc:XYDiagram2D EnableAxisXNavigation"True"><dxc:LineSeries2D x:Name"series" CrosshairLabelPattern"{}{A} : {V:F2}"/></dxc:XYDi…

【概率统计】生存分析

什么是生存分析 激励例子:新药的临床试验 想象一下&#xff0c;有一种新药被开发出来&#xff0c;可以延长某种恶性癌症患者的生命。为了评估药物的有效性&#xff0c;需要进行临床试验&#xff0c;对患者进行一段时间的跟踪&#xff0c;看看他们开始治疗后能活多久。 以下是…

嵌入式-stm32-SR04超声波测距介绍及实战

一&#xff1a;超声波传感器介绍 1.1、SR04超声波测距硬件模块 1.2、SR04的四个IO口 vcc:提供电源5V gnd:接地 Trig:是**发送**声波信号的触发器 Echo:是**接收**回波信号的引脚 当TRIG信号被触发时&#xff0c;传感器会发送一定频率的声波信号&#xff0c;该信号被反射后&am…

Android中_Service生命周期和AMS流程的创建

Service生命周期可以结合Android生命周期分析。 Service生命周期可以从两种启动Service的模式开始讲起&#xff0c;分别是context.startService()和context.bindService()。 Service的生命周期与启动和绑定状态相关。当调用startService()方法启动服务时&#xff0c;会执行onS…

【DeepLearning】Deep Residual Learning for Image Recognition恺神大作学习

[TOC] Deep Residual Learning for Image Recognition 论文 1. 文章主要想解决什么问题&#xff0c;用了什么方法 深度神经网络在训练过程中的3个关键问题&#xff1a; 梯度消失/爆炸问题&#xff1a;随着网络层数的增加&#xff0c;梯度在反向传播过程中可能会变得非常小&a…

Linux磁盘清理(/dev/vda1 100%)已解决

背景&#xff1a;linux上传资源的时候&#xff0c;size总是为0&#xff0c;或者有时候多文件上传&#xff0c;总是传到一半就失败了 原因&#xff1a;磁盘空间不够 查看磁盘空间命令 df -h结果发现 /dev/vda1 20G 19G 0 100% /none 4.0K 0 4.0K…

Hooked协议掀起WEB3新浪潮

随着区块链技术和加密货币的兴起&#xff0c;币圈已经成为全球范围内的一个热门领域。在这个充满机遇与挑战的行业中&#xff0c;Hook机制正逐渐成为一种重要的技术手段&#xff0c;为投资者、开发者以及相关机构提供了更多的选择和可能性。本文将详细介绍币圈中的Hook机制&…

腾讯云4核8G服务器三年优惠价格表

腾讯云轻量服务器4核8G12M有三年优惠价吗&#xff1f;有&#xff0c;但是不怎么优势&#xff0c;相对于云轻量2核2G4M带宽三年价格是540元、2核4G5M带宽3年优惠价756元&#xff0c;4核8G12M轻量应用服务器三年价格是5292元&#xff0c;怎么样&#xff1f;还想买吗&#xff1f;阿…

python3下载手机安卓版,python下载手机版最新

大家好&#xff0c;小编为大家解答python3下载手机安卓版的问题。很多人还不知道python下载手机版最新&#xff0c;现在让我们一起来看看吧&#xff01; 1、先去python官网下载python3的源码包&#xff0c;网址&#xff1a;https://www.python.org/ 1)进去之后点击导航栏的Down…