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

Promise/A+ 规范:引用不可变 + 核心术语(对象 / 函数)详解

Promise/A 规范引用不可变 核心术语对象 / 函数详解文章目录Promise/A 规范引用不可变 核心术语对象 / 函数详解前言一、“引用不可变” 是什么意思二、为什么要强调 “引用不可变”三、代码示例3.1 正确情况Promise 引用不可变实际运行效果3.2 错误假设如果 Promise 引用可变会炸四、解释术语中的“对象或函数”4.1 先搞懂 JavaScript 里「函数」和「对象」的关系4.2 为什么 Promise 定义成「对象或函数」4.3 为什么 Thenable 也定义成「对象或函数」4.4 核心术语对照表优化版术语补充说明总结前言在 Promise/A 规范的核心术语中有两个非常关键、但容易被忽略的细节一是异步结果的「引用不可变」二是规范定义中「Promise / Thenable 是对象或函数」。很多开发者知道 Promise 状态一旦确定就不能修改却不清楚“引用不可变”到底是什么意思也有很多人疑惑为什么规范要写「对象或函数」函数为什么也算在内本文把这两个知识点彻底讲透帮你真正理解 Promise 底层规范写出更严谨、可靠的异步代码。一、“引用不可变” 是什么意思在 JavaScript 里引用不可变指的是当 Promise 被决议成功 / 失败后它的value成功结果或reason失败原因一旦确定就永远不会再改变。用去判断这个值的引用结果永远是true不会因为后续代码而变化。注意这里说的是引用本身不可变不是指值的内部属性不可修改。如果value是一个对象 / 数组你依然可以修改它的属性 / 元素但 Promise 永远不会把这个value替换成另一个全新的对象 / 值。例如对象类型的 value内部属性可以改但引用本身也就是它在内存中的 “身份”永远不变Promise 也不会把它替换成一个全新的值。constobj{name:Alice};constpPromise.resolve(obj);p.then(val{val.nameBob;// ✅ 可以修改对象内部属性console.log(valobj);// true → 引用没变});// 一旦 p Promise.resolve(obj) 决议完成就永远无法让 p 再 resolve 成另一个全新对象比如 { name: Charlie }只能修改现有对象的属性。例如数组版示例内部可改引用不变// 1. 创建一个数组constarr[10,20,30];// 2. 用这个数组创建 PromiseconstpPromise.resolve(arr);p.then(val{// ✅ 可以修改数组内部的元素、push、pop 都行val.push(40);val[0]999;console.log(val);// 输出[999, 20, 30, 40]console.log(valarr);// true → 引用完全没变});// 重点// 你永远不能让 p 再变成另一个全新的数组// 引用永远锁定不会变通俗来讲引用不可变 房子地址永远不变修改属性 / 元素 装修房子、换家具。房子还是那栋房子引用不变只是里面东西变了内容可变。二、为什么要强调 “引用不可变”核心目的是为了保证异步编程的可靠性与可预测性主要有这几点避免竞态与数据不一致Promise 可以被多个.then()同时监听如果决议后还能被篡改不同回调可能拿到不同版本的值导致逻辑混乱、难以调试。引用不可变让所有回调都看到同一个结果行为稳定可预期。符合 “一次性决议” 的核心设计Promise 只能从pending → fulfilled/rejected状态不可逆。既然状态不可逆承载结果的value/reason也必须是一次性确定的否则就违背了 “决议后不再变化” 的契约。方便缓存与共享因为引用不变你可以安全地把 Promise 或它的结果缓存、传递给多处使用不用担心别人偷偷修改结果降低了代码的耦合与风险。与 JavaScript 语言特性对齐JS 中是判断引用是否相同的核心运算符强调 “判定不变”就是明确告诉开发者这个值的身份标识是稳定的不会在决议后被替换成新对象避免了引用变化带来的隐蔽 Bug。一句话总结“引用不可变” Promise 决议后它的结果值 / 失败原因永远不会被整体替换只能在内部修改如果是对象 / 数组所有监听这个 Promise 的回调都会看到同一个引用。这么做是为了让异步代码更稳定、可预测、易维护 。三、代码示例下面用两段极简代码让你一眼看懂什么是 Promise 引用不可变以及如果可变会出现什么灾难。3.1 正确情况Promise 引用不可变实际运行效果// 1. 创建一个对象constperson{name:小明};// 2. 用这个对象创建 PromiseconstpromisePromise.resolve(person);// 3. 监听结果promise.then((res){console.log(第一次拿到结果,res);// { name: 小明 }console.log(引用是否相同,resperson);// true ✔️});// 4. 尝试修改 person 的属性允许person.name小红;// 5. 再次监听同一个 Promisepromise.then((res){console.log(第二次拿到结果,res);// { name: 小红 }console.log(引用依然相同,resperson);// true ✔️});// 关键永远无法把 promise 的结果改成【另一个全新对象】// promise 决议后引用永远不变结论引用不可变 这个意思对象内部可以改引用本身永远不会被替换成新对象所有.then()拿到的永远是同一个引用3.2 错误假设如果 Promise 引用可变会炸// 模拟一个“坏 Promise”结果可以被随便改letbadResult{name:初始值};constbadPromise{then:(cb)cb(badResult),};// 第一次监听badPromise.then((res){console.log(A 组件拿到,res.name);// 初始值});// 中途被别人篡改结果badResult{name:被恶意修改了};// 引用直接变了// 第二次监听badPromise.then((res){console.log(B 组件拿到,res.name);// 被恶意修改了});后果不同时间、不同组件拿到完全不一样的值异步逻辑彻底混乱无法调试、无法信任、无法缓存四、解释术语中的“对象或函数”为什么规范里写「对象或函数」这是 ECMAScript 官方规范的严谨写法不是笔误也不是多余。下面我们彻底讲透4.1 先搞懂 JavaScript 里「函数」和「对象」的关系在 JS 里函数本质上是「可调用的对象」所有函数都是 Function 构造函数的实例而 Function 继承自 Object所以函数 ≠ 普通对象但函数「是对象」同时拥有对象的所有特性验证typeof Promise functiontypeof new Promise((){}) object4.2 为什么 Promise 定义成「对象或函数」① 「对象」覆盖我们日常用的 Promise 实例这是 99% 的开发场景我们通过 new Promise() 创建的实例 p就是一个对象它有.then()方法完全符合 Promise 规范。constpnewPromise(resolveresolve(1));console.log(typeofp);// object② 「函数」覆盖 Promise 构造函数本身Promise 本身是一个构造函数规范必须把「函数」写进去才能保证Promise 构造函数本身也符合 Promise 的定义虽然我们几乎不会直接调用 Promise.then()但从规范严谨性上必须覆盖这个特例。console.log(typeofPromise);// function4.3 为什么 Thenable 也定义成「对象或函数」核心逻辑Thenable 是「类 Promise 对象」是 Promise 规范的「超集」只要一个东西不管是对象还是函数有 .then() 方法就属于 Thenable目的是为了互操作性让非标准 Promise比如 jQuery 的 Deferred、自定义异步对象能和标准 Promise 无缝兼容比如你可以把一个自定义的「有 then 方法的函数」传给Promise.resolve()它会被当成 Promise 处理代码验证对象 / 函数两种形式:// 1. 普通对象形式的 ThenableconstthenableObj{then(resolve){resolve(1);}};Promise.resolve(thenableObj).then(vconsole.log(v));// 1// 2. 函数形式的 Thenable符合规范定义functionthenableFn(){}thenableFn.thenfunction(resolve){resolve(2);};Promise.resolve(thenableFn).then(vconsole.log(v));// 24.4 核心术语对照表优化版术语规范定义通俗理解Promise一个对象或函数包含一个then方法且该方法的行为符合 ECMAScript Promise 规范标准异步结果的容器。日常开发中它是我们通过new Promise()创建的对象但从规范严谨角度Promise构造函数本身是函数。核心特征是拥有.then()方法。Thenable一个定义了then方法的对象或函数类 Promise 对象 (Promise-like)。它不是标准 Promise但只要具备.then()方法就能被标准 Promise 处理核心作用是实现非标准异步对象与标准 Promise 的互操作。术语补充说明以下两点帮你彻底理解「为什么包含函数」Promise 包含「函数」的原因在 JS 中函数是一种特殊的可执行对象。规范写「对象或函数」是为了覆盖Promise 构造函数typeof Promise function这一特例确保定义的严谨性日常场景虽只用到实例对象但规范必须完整。Thenable 包含「函数」的原因这里的「函数」指代任何挂载了then方法的自定义函数。只要满足「有 then 方法」这一条件标准 Promise 就能将其视为类 Promise 对象进行解析实现跨库 / 跨框架的异步兼容。总结引用不可变Promise 一旦决议成功 / 失败它的结果 value / 失败原因 reason 的引用永远不变。你可以修改对象/数组内部属性但不能替换成全新的引用保证异步结果稳定、可预测、可缓存。核心术语对象或函数Promise 是对象或函数是标准异步容器拥有符合规范的 then 方法。Thenable 是拥有 then 方法的对象或函数用于实现 Promise 互操作性。函数之所以被包含是因为 JS 中函数是特殊对象且 Promise 构造函数本身就是 function。理解这两点是吃透 Promise/A 规范、掌握异步底层逻辑的关键一步。

相关文章:

Promise/A+ 规范:引用不可变 + 核心术语(对象 / 函数)详解

Promise/A 规范:引用不可变 核心术语(对象 / 函数)详解 文章目录Promise/A 规范:引用不可变 核心术语(对象 / 函数)详解前言一、“引用不可变” 是什么意思?二、为什么要强调 “引用不可变”&…...

读2025世界前沿技术发展报告30海洋技术发展(下)

1. 强化无人及反无人作战能力建设1.1. 英美发布相关战略文件,顶层规划无人、反无人作战能力建设1.1.1. 《无人机战略》文件,分析无人系统对传统战争形态转变的影响1.1.2. 《反无人系统战略》1.1.2.1. ​包括设立联合反小型无人机系统办公室(J…...

Git 仓库搬家后,如何让本地仓库“认新家”?——小白也能看懂的远程地址修改指南

Git 仓库搬家后,如何让本地仓库“认新家”?——小白也能看懂的远程地址修改指南 一句话总结:当你的 Git 仓库迁移到新地址后,只需更新本地仓库的“通讯录”,并告诉 Git “以后默认推送到新家”,即可无缝切换…...

简单工厂、工厂方法、抽象工厂的PHP代码区别?

这三个模式名字很像,但解决的问题层级和代码结构完全不同。 简单工厂 (Simple Factory):一个类包办所有创建逻辑(违反开闭原则)。工厂方法 (Factory Method):每个产品对应一个工厂子类(针对一个产品等级&am…...

在Windows系统下使用fastboot命令

在Windows系统下使用fastboot命令第一步:确认工具已就绪第二步:让手机进入 Fastboot 模式方法 A:通过 ADB 命令重启(推荐,需先连接 ADB)方法 B:物理按键组合(手机关机状态下&#xf…...

如何用PHP实现线程安全的单例模式?

标准的 PHP-FPM 架构下,根本不存在“多线程”,因此也不需要“线程安全”的单例模式。 PHP 的设计哲学是 Share-Nothing(无共享)。 FPM 模式:每个请求由一个独立的进程处理。进程之间内存隔离。你在进程 A 里的单例&…...

提升开发效率:用快马一键生成智能排序工具模块

在开发过程中,排序功能几乎是每个项目都会用到的核心模块。无论是处理用户数据、展示商品列表,还是分析日志信息,一个高效可靠的排序工具都能大幅提升开发效率。最近我在InsCode(快马)平台上尝试生成智能排序模块,发现整个过程比想…...

告别繁琐安装:用快马平台在线环境,三步创建你的第一个网页应用

作为一个刚入门的前端开发者,我最近发现了一个特别适合新手快速上手的开发方式——不用下载任何软件,直接在浏览器里就能完成网页开发的全流程。今天想和大家分享这个超实用的发现,以及我是如何用它快速做出第一个网页应用的。 传统开发环境的…...

智能化磁盘空间革命:CleanMyWechat如何一键释放微信PC端数十GB存储空间

智能化磁盘空间革命:CleanMyWechat如何一键释放微信PC端数十GB存储空间 【免费下载链接】CleanMyWechat 自动删除 PC 端微信缓存数据,包括从所有聊天中自动下载的大量文件、视频、图片等数据内容,解放你的空间。 项目地址: https://gitcode…...

基于vue3与pinia构建电商核心模块,快马平台实战演练购物车与商品列表

基于vue3与pinia构建电商核心模块,快马平台实战演练购物车与商品列表 最近在做一个电商项目,需要快速搭建商品展示和购物车功能。经过一番调研,我选择了Vue3 Pinia的组合,配合Vue Router实现页面跳转。整个过程在InsCode(快马)平…...

硬件笔记——立创逻辑派开关电源案例解读

立创逻辑派开发板中有上图三个BUCK电路,使用SY8113B芯片将5V电压分别降压至3.3V、1.5V、1.0V。 SY8113B 是一款同步降压型稳压 IC,它将 PWM 控制模块、高端开关管与低端开关管集成在同一芯片上,以此最大限度降低开关转换损耗与导通损耗。凭借超低导通电阻Rds (on)的…...

2025届学术党必备的AI科研助手实测分析

Ai论文网站排名(开题报告、文献综述、降aigc率、降重综合对比) TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 为要切实有效降低AIGC内容的可被识别程度,我们是能够从生成这个关键阶段以及后处…...

零root权限+40%成本下降!OpenClaw Podman容器化部署全攻略,AWS Graviton+ECR打造AI Agent生产环境

本文已收录于《OpenClaw 实战指南》专栏,所有方案均经过AWS生产环境反复验证,覆盖从环境初始化到高可用集群部署全流程,附可直接复制的标准化部署脚本、Dockerfile模板、IAM权限配置与高频踩坑解决方案,适合AI Agent开发者、DevOp…...

pySLAM体素重建技术:TSDF与高斯泼溅的深度解析

pySLAM体素重建技术:TSDF与高斯泼溅的深度解析 【免费下载链接】pyslam pySLAM is a hybrid Python/C Visual SLAM pipeline supporting monocular, stereo, and RGB-D cameras. It provides a broad set of modern local and global feature extractors, multiple …...

医护版手术室大屏实战开发

医护版手术室大屏设计与实现 引言 在医院手术室管理中,实时了解手术排程和状态对于提高医疗效率至关重要。本文将介绍一个基于ASP.NET Core和原生JavaScript实现的手术室大屏系统,该系统能够实时展示当日手术安排、手术状态,并提供直观的视觉…...

多账号管理工具效率提升指南:AUTO-MAS自动化脚本全攻略

多账号管理工具效率提升指南:AUTO-MAS自动化脚本全攻略 【免费下载链接】AUTO-MAS 多脚本多配置统一管理与自动化工具 | 轻松管理大量脚本并存储多个用户配置、设计自动化任务流、监看脚本日志,大幅提高自动化代理效率与稳定性! 项目地址: …...

HarmonyOS 6实战:HarmonyOS轻量化交互的两种方案改造与实践(上)

HarmonyOS 6实战:HarmonyOS轻量化交互的两种姿势(上篇)一、服务卡片:AI助手实现常驻系统页服务卡片改造实战踩坑记录二、实况窗:更新位置与进程服务(mock版)生命周期管理踩坑记录总结我们之前做…...

Oracle EBS和SAP在资产类别层级关系上的差异

Oracle EBS和SAP在资产类别层级关系上的差异。核心差异对比维度Oracle EBSSAP资产类别结构支持多层级(父子关系)扁平结构(无层级)典型层级主类别 → 子类别 → 细分类别单一类别代码灵活性可逐级继承/覆盖属性每个类别独立定义全部…...

Oracle EBS 资产类别是 真正的树形层级结构(通过弹性域实现父子关系),而 SAP 资产类别(Asset Class)是 扁平结构(无系统内置层级)

Oracle EBS 资产类别是 真正的树形层级结构(通过弹性域实现父子关系),而 SAP 资产类别(Asset Class)是 扁平结构(无系统内置层级)。下面通过详细原理、实例、配置、报表四个维度彻底对比分析。一…...

【ESP32-S3 深度实战】从小智AI底层移植到自定义LVGL表情:M5Stack CoreS3 避坑与架构指南

大家好,这里是企鹅的蚂蚁! 继上一篇打通了 M5Stack CoreS3 的 LVGL 模拟器与全双工音频后,最近我又开启了一项“硬核战役”:尝试将目前非常火的“小智 AI”底层框架移植进 CoreS3,并且完全弃用它原生的 UI&#xff0c…...

AI学习笔记二

一,NumPy库1,定义NumPy 是 Python 科学计算的核心库,专为多维数组(ndarray) 设计,比 Python 原生列表快 10~100 倍,是数据分析、机器学习、深度学习的基础。2,基础代码示例import nu…...

PvZ Toolkit:3步解锁植物大战僵尸终极游戏增强工具,打造完全自定义体验

PvZ Toolkit:3步解锁植物大战僵尸终极游戏增强工具,打造完全自定义体验 【免费下载链接】pvztoolkit 植物大战僵尸 PC 版综合修改器 项目地址: https://gitcode.com/gh_mirrors/pv/pvztoolkit 还在为植物大战僵尸的传统玩法感到乏味吗&#xff1f…...

适配新的gps模块,在Android系统中注意哪些问题

首先理解Android LocationManager与GNSS硬件适配深度涵盖LocationManager功能、GNSS芯片适配接口、文件系统依赖、调试实战四大模块,“LocationManager是Android定位服务的总入口,GNSS HAL层适配,从芯片驱动到Framework层回调,完整…...

MySQL函数及条件查询相关用法

文章目录 前言 一、函数(可跳过) 1.字符串函数 2.数值函数 3.日期和时间函数 4.聚合函数(常用) 5.控制流函数 6.加密和压缩函数 7.系统信息函数 二、条件查询(select) 1.筛选条件子句where与hav…...

LLM 怎么生成回答?揭秘“思考“过程

系列:大语言模型原理科普(5 篇) 本篇:第 3 篇 难度:⭐⭐ 零基础 浅显技术 字数:约 9500 字 阅读时间:20 分钟📖 开篇:你输入问题后,发生了什么? …...

面试“逆袭率”第一的秘密:让我为你细细阐述

报名前,我做足了功课。张永老师深耕贵州公考面试教学12年,这些年来,他带出的学员上岸率在业内是公认的。他教出的高分学员数量业内最高,这些实实在在的数据,远比“名师”两个字有说服力。真正让我服气的,是…...

GHelper:华硕笔记本的终极开源性能控制解决方案

GHelper:华硕笔记本的终极开源性能控制解决方案 【免费下载链接】g-helper Lightweight, open-source control tool for ASUS laptops and ROG Ally. Manage performance modes, fans, GPU, battery, and RGB lighting across Zephyrus, Flow, TUF, Strix, Scar, an…...

DREAM3D:革新材料科学数据处理的开源框架

DREAM3D:革新材料科学数据处理的开源框架 【免费下载链接】DREAM3D Data Analysis program and framework for materials science data analytics, based on the managing framework SIMPL framework. 项目地址: https://gitcode.com/gh_mirrors/dr/DREAM3D …...

在快马平台实战演练claude代码技能教程中的完整项目开发流程

今天想和大家分享一个特别实用的学习路径——如何通过InsCode(快马)平台将Claude代码技能教程中的知识转化为真实可运行的项目。最近我跟着教程完整实现了一个博客内容管理系统,整个过程比想象中顺畅很多。 项目规划与功能拆解 Claude教程中提到的博客系统包含8个…...

3步解锁音乐自由:NCMDump让NCM格式转换零门槛

3步解锁音乐自由:NCMDump让NCM格式转换零门槛 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 问题破局篇:被囚禁的音乐,你遇到过吗? 你是否经历过这些尴尬场景:下载了喜欢…...