当前位置: 首页 > news >正文

测试驱动来学习 Promise

基础功能

  • 测试案例:以同步的方式调用。
/*** v1: 基础功能*/
const p1 = new MyPromise((resolve, reject) => {resolve('success')reject('error')
})p1.then((value) => {console.log('v1: ', value)
}) 
  • 实现功能:在 status 和 value 的位置暂存值,在 then 函数中取出。
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'class MyPromise {status = PENDING;value = null;constructor(executor) {executor(this.resolve, this.reject);}resolve = (value) => {if (this.status === PENDING) {this.status = FULFILLED;this.value = value;}}reject = (value) => {if (this.status === PENDING) {this.status = REJECTED;this.value = value;}}then = (onFulfilled, onRejected) => {const callbackMap = {[FULFILLED]: onFulfilled,[REJECTED]: onRejected}callbackMap[this.status]?.(this.value)}
}

异步执行

  • 测试案例
/*** v2: 异步执行*/
const p2 = new MyPromise((resolve, reject) => {setTimeout(() => {resolve('success') // 异步结束后调用}, 1000)
})p2.then((value) => {console.log('v2: ', value)
})
  • 实现功能
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'class MyPromise {status = PENDING;value = null;fulfilledCallback = null; // 暂存 rejectrejectedCallback = null; // 暂存 rejectconstructor(executor) {executor(this.resolve, this.reject);}resolve = (value) => {if (this.status === PENDING) {this.status = FULFILLED;this.value = value;this.fulfilledCallback?.(value); // 异步结束后调用 resolve}}reject = (value) => {if (this.status === PENDING) {this.status = REJECTED;this.value = value;this.rejectedCallback?.(value); // 异步结束后调用 reject}}then = (onFulfilled, onRejected) => {const callbackMap = {[FULFILLED]: onFulfilled,[REJECTED]: onRejected,[PENDING]: () => {this.fulfilledCallback = onFulfilled;this.rejectedCallback = onRejected;}}callbackMap[this.status]?.(this.value)}
}

异步时多个then

  • 测试案例
/*** v3: 异步时多个then*/
const p3 = new MyPromise((resolve, reject) => {setTimeout(() => {resolve('success')}, 1000)
})p3.then((value) => {console.log('v3 - 1: ', value)
})
p3.then((value) => {console.log('v3 - 2: ', value)
})
// v3 - 1:  success
// v3 - 2:  success
  • 实现功能
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'class MyPromise {status = PENDING;value = null;fulfilledCallbacks = []; // 暂存 resolverejectedCallbacks = []; //  暂存 rejectconstructor(executor) {executor(this.resolve, this.reject);}resolve = (value) => {if (this.status === PENDING) {this.status = FULFILLED;this.value = value;while (this.fulfilledCallbacks.length) { // 遍历执行所有的 resolvethis.fulfilledCallbacks.shift()?.(value);}}}reject = (value) => {if (this.status === PENDING) {this.status = REJECTED;this.value = value;while (this.rejectedCallbacks.length) { // 遍历执行所有的 rejectthis.rejectedCallbacks.shift()?.(value);}}}then = (onFulfilled, onRejected) => {const callbackMap = {[FULFILLED]: onFulfilled,[REJECTED]: onRejected,[PENDING]: () => {this.fulfilledCallbacks.push(onFulfilled);  // 异步时多个thenthis.rejectedCallbacks.push(onRejected);}}callbackMap[this.status]?.(this.value)}
}

链式调用

  • 测试案例
const p4 = new MyPromise((resolve, reject) => {setTimeout(() => {resolve('success')}, 1000)
})p4.then((value) => {console.log('v4 - 1: ', value)return 1;
}).then((value) => {console.log('v4 - 2: ', value)return 2;
})
// v4 - 1:  success
// v4 - 2:  1
  • 实现功能
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'class MyPromise {status = PENDING;value = null;fulfilledCallbacks = [];rejectedCallbacks = [];constructor(executor) {executor(this.resolve, this.reject);}resolve = (value) => {if (this.status === PENDING) {this.status = FULFILLED;this.value = value;while (this.fulfilledCallbacks.length) {this.fulfilledCallbacks.shift()?.(value);}}}reject = (value) => {if (this.status === PENDING) {this.status = REJECTED;this.value = value;while (this.rejectedCallbacks.length) {this.rejectedCallbacks.shift()?.(value);}}}then = (onFulfilled, onRejected) => {return new MyPromise((resolve, reject) => {const fulfilledTask = (value) => {const res = onFulfilled(value); // 将上一个 Promise 的 resolve 结果传入当前 Promiseresolve(res);   // 确保返回的 Promise 被执行}const rejectedTask = (value) => {const res = onRejected(value);reject(res);    // 确保返回的 Promise 被执行}const callbackMap = {[FULFILLED]: fulfilledTask,[REJECTED]: rejectedTask,[PENDING]: () => {this.fulfilledCallbacks.push(fulfilledTask);  // 异步时多个thenthis.rejectedCallbacks.push(rejectedTask);    // 异步时多个then}}callbackMap[this.status]?.(this.value)})}
}

返回自身

  • 测试案例
/*
* v6: 返回自身
*/
const p6 = new MyPromise((resolve, reject) => {resolve(1);
});const p62 = p6.then((res) => {console.log(res);return p62;
});
p62.then(() => { },(err) => console.log(err)
);

相关文章:

测试驱动来学习 Promise

基础功能 测试案例:以同步的方式调用。 /*** v1: 基础功能*/ const p1 new MyPromise((resolve, reject) > {resolve(success)reject(error) })p1.then((value) > {console.log(v1: , value) }) 实现功能:在 status 和 value 的位置暂存值&…...

Vue3实战笔记(20)—封装头部导航组件

文章目录 前言一、封装头部导航栏二、使用步骤总结 前言 Vue 3 封装头部导航栏有助于提高代码复用性、统一风格、降低维护成本、提高可配置性和模块化程度,同时还可以实现动态渲染等功能,有利于项目开发和维护。 一、封装头部导航栏 封装头部导航栏&am…...

Yolov8目标检测——在Android上部署Yolov8 tflite模型

1. 简介 YOLOv8 是一种用于目标检测的深度学习模型,它是 YOLO(You Only Look Once)系列的最新版本之一。YOLO 系列因其高效和准确性而在计算机视觉领域非常受欢迎,特别是在需要实时目标检测的应用中,如视频监控、自动…...

(delphi11最新学习资料) Object Pascal 学习笔记---第12章操作类(类方法和类数据)

第12章 操作类 ​ 在过去的几章中,你已经了解了 Object Pascal 语言面向对象的基础:类、对象、方法、构造函数、继承、后期绑定、接口等等。现在,我们需要进一步了解与类管理相关的一些更高级、更具体的语言特性。从类引用到类助手(class he…...

面向 C# 开发人员的电子邮件转换控件 - EML 到 PNG

本文将使 C# 开发人员能够以编程方式将EML或MSG转换为其他流行的文件格式。Aspose.Email 提供了类和方法以及在线 电子邮件转换器工具,可将 EML无缝转换为PNG 。如果不安装第三方软件,则无法打开 EML/MSG 文件。因此,将 EML/MSG 转换为 PNG 和…...

Vue3:数据交互axios

回调函数 > 回调函数: 一些特殊的函数,表示未来才会执行的一些功能,后续代码不会等待该函数执行完毕就开始执行了 1. Promise 1.1 简介 > 前端中的异步编程技术,类似Java中的多线程线程结果回调! * Promise 是异步编程的一种解决方案&#xff0c…...

芯片的性能指什么

【省带宽、压成本专题】降低30%视频码率,深挖“窄带高清”的实现原理 - 知乎 芯片(或微处理器、集成电路)的性能主要指其完成特定任务的能力和效率。性能可以通过多种参数来衡量,这些参数反映了芯片设计的不同方面,包…...

Java通过百度地图API获取定位-普通IP定位

项目中有一个登录邮箱提醒的功能,需要根据IP地址获取定位信息,从而更好地提示用户账号登录的所在地。为此,花费了一些时间来实现这个功能。 在CSDN搜索了一下,发现关于获取定位的文章说明都不够详细,于是决定自己创作一…...

5月13号作业

使用消息队列实现的2个终端之间的互相聊天 并使用信号控制消息队列的读取方式: 当键盘按ctrlc的时候,切换消息读取方式,一般情况为读取指定编号的消息,按ctrlc之后,指定的编号不读取,读取其他所有编号的消息…...

【计算机网络】Socket网络编程

💻文章目录 📄前言Socket编程基础概念工作原理 Socket API介绍socket函数绑定、监听函数accept、connect接受/发送函数 Socket API的应用Socket类与其派生类的设计服务器与客户端的设计使用 📓总结 📄前言 现今我们的日常生活当中…...

Ansible自动运维工具之playbook

目录 一.inventory主机清单 1.定义 2.变量 (1)主机变量 (2)组变量 (3)组嵌套 二.playbook基本内容 1.组成 (1)Tasks: 任务,即调用模块完成的某操作 &#xff0…...

【启明智显技术分享】SSD201/SSD202D核心板UI界面开发全攻略:LVGL使用指南

提示:作为Espressif(乐鑫科技)大中华区合作伙伴及sigmastar(厦门星宸)VAD合作伙伴,我们不仅用心整理了你在开发过程中可能会遇到的问题以及快速上手的简明教程供开发小伙伴参考。同时也用心整理了乐鑫及星宸…...

数据可视化(九):Pandas北京租房数据分析——房源特征绘图、箱线图、动态可视化等高级操作

Tips:"分享是快乐的源泉💧,在我的博客里,不仅有知识的海洋🌊,还有满满的正能量加持💪,快来和我一起分享这份快乐吧😊! 喜欢我的博客的话,记得…...

ADOP带你了解:跳线与交叉电缆有何不同?

如果您想将设备连接到互联网,您可能想知道要使用的正确电缆。跳线和交叉电缆都是类型的以太网电缆,可帮助连接计算机、调制解调器、路由器和交换机等设备。那么,跳线和交叉电缆有什么区别呢?让我们讨论这两种类型的电缆&#xff0…...

Django 和 Spring Boot

标题 Django (Python)Django提供的组件Django 的处理逻辑 Spring Boot (Java)Spring Boot 的特点Spring Boot 的处理逻辑 MVC设计模式模型(Model)视图(View)控制器(Controller)逻辑处理过程 Django 和 Spri…...

上位机图像处理和嵌入式模块部署(树莓派4b的替代品)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 实话实说,树莓派4b的产品力还是比较优秀的,价格还算适中。但是和国产卡片电脑比起来,则逊色不少。功能差不多的…...

Springboot整合 Spring Cloud Gateway

1.Gateway介绍 1.是spring cloud官方推出的响应式的API网关框架,旨在为微服务架构提供一种简单有效的API路由的管理方式,并基于Filter的方式提供网关的基本功能,例如:安全认证,监控,限流等等。 2.功能特征…...

Rust开发工具有哪些?

目录 一、JetBrains公司的RustRover​编辑 二、微软公司的Visual Studio Code 三、Rust编译工具 一、JetBrains公司的RustRover RustRover是由JetBrains开发的一款专为Rust开发量身定制的新兴IDE,目前还处于早期访问阶段。它支持Rust、Cargo、TOML、Web和数据库等…...

20240514基于深度学习的弹性超材料色散关系预测与结构逆设计

论文:Dispersion relation prediction and structure inverse design of elastic metamaterials via deep learning DOI:https://doi.org/10.1016/j.mtphys.2022.100616 1、摘要 精心设计的超材料结构给予前所未有的性能,保证了各种各样的具…...

SAP:FI 财务凭证行项目文本前台修改

一、问题描述 财务凭证行项目文本点击修改,但是前台有的行可以修改,有的行是灰色的不能修改,如下图所示,这个文本信息有误,必须修改怎么办? 二、思路分析 有的行可以修改,有的行不能修改&#x…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命

在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

基于IDIG-GAN的小样本电机轴承故障诊断

目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) ​梯度归一化(Gradient Normalization)​​ (2) ​判别器梯度间隙正则化(Discriminator Gradient Gap Regularization)​​ (3) ​自注意力机制(Self-Attention)​​ 3. 完整损失函数 二…...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)

macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 🍺 最新版brew安装慢到怀疑人生?别怕,教你轻松起飞! 最近Homebrew更新至最新版,每次执行 brew 命令时都会自动从官方地址 https://formulae.…...

CppCon 2015 学习:Time Programming Fundamentals

Civil Time 公历时间 特点: 共 6 个字段: Year(年)Month(月)Day(日)Hour(小时)Minute(分钟)Second(秒) 表示…...

在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南

在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南 背景介绍完整操作步骤1. 创建Docker容器环境2. 验证GUI显示功能3. 安装ROS Noetic4. 配置环境变量5. 创建ROS节点(小球运动模拟)6. 配置RVIZ默认视图7. 创建启动脚本8. 运行可视化系统效果展示与交互技术解析ROS节点通…...

flow_controllers

关键点: 流控制器类型: 同步(Sync):发布操作会阻塞,直到数据被确认发送。异步(Async):发布操作非阻塞,数据发送由后台线程处理。纯同步(PureSync…...