当前位置: 首页 > 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…...

终极指南:使用eksctl Karpenter支持实现AWS EKS集群智能节点调度和成本优化

终极指南:使用eksctl Karpenter支持实现AWS EKS集群智能节点调度和成本优化 【免费下载链接】eksctl The official CLI for Amazon EKS 项目地址: https://gitcode.com/gh_mirrors/ek/eksctl eksctl作为Amazon EKS的官方命令行工具,提供了强大的K…...

Qt项目实战:借助Valgrind精准定位与修复内存泄漏

1. 为什么Qt开发者需要Valgrind 刚接触Qt开发时,我总以为用了智能指针和Qt自带的内存管理机制就能高枕无忧。直到某个深夜,项目上线前突然崩溃,日志里只有一句"segmentation fault",我才意识到内存问题有多可怕。那次经…...

将软件需求“翻译”成硬件语言:一份让设计团队无法拒绝的黄金文档

该文章同步至公众号OneChan ——如何用硬件工程师的思维,赢得他们的尊重与代码 你提交的不是一份“需求清单”,而是一份“缺陷预防方案”和“效率提升指南”。 引言:一次代价高昂的“翻译失败” 数年前,我参与一个关键IP的开发。…...

Switch破解新选择:大气层系统稳定版完整安装与优化指南

Switch破解新选择:大气层系统稳定版完整安装与优化指南 【免费下载链接】Atmosphere-stable 大气层整合包系统稳定版 项目地址: https://gitcode.com/gh_mirrors/at/Atmosphere-stable 想要让你的Switch焕发新生,体验自制软件和游戏优化的无限可能…...

TP4054锂电池充电管理库原理与嵌入式工程实践

1. TP4054线性锂离子电池充电管理库深度解析与工程实践TP4054是一款由南京拓微电子(Top Power)推出的高集成度、单节锂离子/锂聚合物电池专用线性充电管理芯片。其典型应用电路仅需极少外围器件,支持恒流/恒压(CC/CV)充…...

2026年4月最新:全职作者深度测评8款AI写长篇小说专业工具,谁能打破“吃设定”与“机器味”魔咒?

到了2026年4月,网文圈的生产方式已经发生了根本性的重构。现在的全职作者,早就不只是单纯地在键盘前死磕字数了。为了在这个极其内卷的市场中活下来,我们不仅要保证每天稳定的更新量,还要考虑 IP 的后续孵化——比如把高光剧情快速…...

计算机毕业设计:Python城市交通出行模式挖掘系统 Django框架 可视化 数据分析 PyEcharts 交通 深度学习(建议收藏)✅

博主介绍:✌全网粉丝10W,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业项目实战6年之久,选择我们就是选择放心、选择安心毕业✌ > 🍅想要获取完整文章或者源码,或者代做,拉到文章底部即可与…...

弯管LRA计算软件(XYZ转LRA)

专业的“弯管LRA计算软件(XYZ转LRA)”,主要用于将弯管在三维空间中的一系列坐标点(XYZ),转换为管道加工所需的关键制造参数,即LRA(直线段长度、旋转角度、弯曲夹角)。界面…...

002.计算机视觉与目标检测发展简史:从传统方法到深度学习

上周调一个老项目,客户要求在不升级硬件的前提下提升夜间车辆检测的准确率。打开代码一看,好家伙,全是手工设计的HOG特征SVM分类器,夜间噪点多的时候误检率直接飙到40%以上。我盯着那些精心调参的边缘梯度直方图代码,突…...

倒排索引详解

文章目录倒排索引(Inverted Index)正排索引与倒排索引实现优缺点倒排索引(Inverted Index) 倒排索引是信息检索领域最核心的数据结构,几乎所有搜索引擎(Google、Elasticsearch、Lucene)都基于它…...