我终于彻底搞懂了 Promise:从「看了无数教程」到「真正理解异步」

这两年我看过市面上几乎所有 Promise 教程,但始终是一知半解。直到我搞清楚了浏览器多线程、事件循环和微任务,才迎来真正的顿悟。 前言:那些年我踩过的坑 Promise 的重要性不言而喻,可就是学不会。我看过阮一峰老师的教程,刷过各种视频,甚至能背出"链式调用、解决回调地狱"这些概念,但一碰到执行顺序的题目就懵。 最大的误解是什么?我以前一直以为"异步"就是 JS单线程同时处理多件事情,好像它能一边倒计时一边执行下面的代码。这种错误认知让我在面对 setTimeout 和 Promise 混用的代码时永远答不对。 直到我读了一篇文章 —— 《从浏览器多进程到JS单线程,JS运行机制最全面的一次梳理》,配合阮一峰的 Promise 教程重新学习,我才真正开了窍。 下面我把这次"顿悟"的过程完整梳理出来,希望能帮助那些和我一样曾经痛苦挣扎的同学。 一、核心突破:理解"单线程异步"的真正含义 误解 vs 真相 我曾经的误解 真正的机制 JS 自己一边倒计时一边执行后面的代码 JS 把定时任务交给浏览器的定时器线程去处理 异步就是单线程来回切换干不同的事 异步是发布订阅模式:订阅事件 → 别的线程执行 → 完成后把回调放回任务队列 Promise 构造函数里的代码也是异步的 Promise 构造函数内的代码同步执行,只有 .then 回调才是微任务 核心记忆:JavaScript 引擎是单线程的,但浏览器是多线程的。 当 JS 遇到 setTimeout(cb, 1000) 时,它不会自己倒计时。它会说:“定时器线程,请你在 1 秒后把这个 cb 函数放回任务队列。“然后自己立刻继续执行后续同步代码。定时器线程倒计时结束后,把 cb 塞进宏任务队列,等待主线程空闲时通过事件循环(Event Loop)取走执行。 这就是你理解的 “Promise 中去使用 event loop 以外的线程,然后发布订阅模式” —— 完全正确。 二、事件循环(Event Loop)与任务队列 一旦理解了上面的外包机制,事件循环就变得非常直观。 1. 两类任务 宏任务(MacroTask):整体 script 代码、setTimeout、setInterval、I/O、UI 渲染。 微任务(MicroTask):Promise.then()、Promise.catch()、MutationObserver。 2. Event Loop 执行顺序 执行一个宏任务(最开始就是整个 script 代码)。 执行过程中产生的所有微任务,放入微任务队列。 当前宏任务执行完毕后,立刻清空整个微任务队列。 进行必要的 UI 渲染。 从宏任务队列中取出下一个宏任务,循环往复。 关键点:微任务的优先级永远高于宏任务。先清空微任务,再取下一个宏任务。 ...

June 9, 2026 · 3 min · 472 words

推荐 | 从浏览器多进程到JS单线程,JS运行机制最全面的一次梳理

本文是个人阅读推荐,非原创。原文作者:腾讯云开发者社区 为什么推荐这篇文章 学 Promise、学 async/await、学事件循环——我相信大部分前端都经历过这个过程:看了无数教程,能背出"链式调用"“解决回调地狱"这些概念,但一碰到执行顺序的题目就懵。 问题出在哪?我们跳过了底层机制,直接去学上层 API。 这篇文章做了一件很多人没做过的事:从浏览器是多进程的这个事实出发,一路梳理到 JS 引擎的单线程本质,再到 Event Loop 的完整机制。 读完之后你会发现,Promise 的所有行为都变得合理且可预测,而不是需要死记硬背的"规则”。 文章讲了什么 大致脉络: 进程 vs 线程 —— 用工厂和工人的比喻讲清楚区别,不啰嗦 浏览器是多进程的 —— 每个 Tab 页是一个独立进程,Browser 进程、GPU 进程、渲染进程各司其职 浏览器内核(渲染进程)内部的线程关系 —— GUI 渲染线程与 JS 引擎线程互斥,这就是为什么 JS 会阻塞页面渲染 JS 引擎的单线程本质 —— JS 引擎线程一次只能做一件事,但浏览器其他线程可以并行 Event Loop 完整机制 —— 宏任务、微任务、任务队列,讲得非常透彻 定时器的真相 —— setTimeout 不是精确计时,而是交给浏览器定时器线程处理 最值得读的部分 我个人觉得最有价值的三个点: ① JS 引擎线程和 GUI 渲染线程互斥 这解释了为什么耗时的 JS 代码会导致页面卡顿——不是因为 JS “慢”,而是因为它们抢同一个线程,JS 执行时页面没法渲染。 ② 异步的本质是"外包" JS 遇到 setTimeout、网络请求等异步操作时,自己不会去做,而是交给浏览器的其他线程(定时器线程、网络线程等),完成后把回调函数放回任务队列,等主线程空闲时再执行。这就是发布订阅模式的实际应用。 ③ 微任务优先级高于宏任务 ...

June 9, 2026 · 1 min · 96 words

微信小程序如何实现 SSE:从原理到生产实践

一、为什么需要 SSE? SSE(Server-Sent Events,服务器推送事件) 是一种基于 HTTP 的单向实时通信协议。与 WebSocket 的全双工不同,SSE 是 服务端 → 客户端 的单向推送,天然适合以下场景: 💬 实时聊天:接收对方发送的消息 🤖 AI 流式输出:ChatGPT 风格的逐字返回 📊 数据看板:实时刷新指标数据 🔔 消息通知:订单状态变更、审核结果推送 相比 WebSocket,SSE 的优势在于: 维度 SSE ✅ SSE ⚠️ 局限 基于 HTTP,天然支持认证、CORS ✅ 单向通信,客户端需另外发请求 自动重连机制(浏览器端) ✅ 浏览器限制最大 6 个并发连接 协议简单,调试方便 ✅ 不支持二进制数据 防火墙友好,不会被拦截 ✅ IE/Edge Legacy 不支持 二、浏览器中的 SSE 长什么样? 在浏览器中,使用 SSE 非常简单: // 浏览器原生 EventSource —— 就这么简单 const es = new EventSource('/api/events'); // 监听默认消息 es.onmessage = (e) => { console.log('收到消息:', JSON.parse(e.data)); }; // 监听自定义事件 es.addEventListener('chat-message', (e) => { const msg = JSON.parse(e.data); renderMessage(msg); }); // 监听连接状态 es.onerror = () => console.log('连接断开,浏览器会自动重连'); 浏览器的 EventSource API 帮你处理了所有脏活累活: ...

June 5, 2026 · 10 min · 1971 words

向老板要预算的神器:WPO Stats —— 一个用数据说话的网站推荐

一个经典的困境 你是一个前端工程师或技术负责人。你发现网站慢得要命,性能指标惨不忍睹。你想花两个 sprint 做性能优化,但老板问了一个问题: “做这个能带来多少收益?” 于是你沉默了。 你知道性能很重要,但你拿不出数据来支撑你的论点。 WPO Stats(wpostats.com)就是为了解决这个问题而生的。 WPO Stats 是什么? 它是由 Web 性能领域两位重量级人物——Tim Kadlec 和 Tammy Everts(著有《Time is Money》)——共同维护的一个非商业项目,一个关于 Web 性能优化(WPO)对业务指标影响的数据案例库。 简单说:这里存了上百个真实世界的研究案例,每个案例都用冷冰冰的数字告诉你——性能优化真的能赚钱。 随便挑几个案例感受一下 Amazon — 页面加载时间每增加 100ms,销售额下降 1%。 Walmart — 页面加载时间从 7 秒优化到 2 秒,转化率提升了 2%。 Sunday Citizen — 优化 Core Web Vitals 后,LCP 改善了 25%,CLS 改善了 61%,跳出率下降 4%,转化率提升超过 6%。 某电商公司 — SpeedSense 帮他们做性能优化后,7.6% 的转化率提升,带来了约 600 万美元的年度收入增长。 这些不是拍脑门吹出来的数字,而是来自真实公司的真实案例,引用的是公开可查的数据来源。 为什么这网站做得很好? 按指标筛选 — 你想论证性能影响转化率?点进去,所有关于转化率的案例列得清清楚楚。影响收入、跳出率、SEO、用户参与度?都有对应的标签分类。 超过十五年跨度 — 数据从 2006 年至今,覆盖的行业包括电商、SaaS、媒体、政府网站等等。不管你在什么行业,大概率能找到跟你相似的案例。 每个案例都有源头 — 不是凭空捏造。每条数据都引用原始来源,可以直接拿来写提案。 ...

June 2, 2026 · 1 min · 124 words

推荐一个网站:martinfowler.com —— 软件工程的思想原野

网站: martinfowler.com 站长: Martin Fowler — Thoughtworks 首席科学家,《重构》《企业应用架构模式》作者 创立时间: 2000 年左右,bliki 始于 2003 年 有些网站,你第一次点进去觉得平平无奇,但第二次、第三次之后,它会慢慢变成你查资料时的默认起点。 martinfowler.com 对我来说就是这样的存在。 一个什么样的网站? 如果用一句话概括,这是一个软件工程的深度内容站。没有广告,没有付费墙,没有"优化阅读体验"的弹窗。就是白底黑字,配上偶尔的代码块和图表。 站长 Martin Fowler 是 Thoughtworks 的 Chief Scientist,写过几本改变行业面貌的书——1999 年的《重构》让"改善既有代码的设计"成为程序员的必修课,2002 年的《企业应用架构模式》给了无数后端开发者一套通用词汇表。 但这不只是他个人的博客。他自己说:“这个网站最开始只是放我自己的文章,但随着它越来越受欢迎,我开始用它帮别人的好文章获得更多曝光。” 于是每篇文章都经过他本人的筛选和编辑——质量远重于数量。这种克制让网站二十多年积累的内容始终保持在一个可被信任的水准上。 Bliki:介于博客和维基之间 2003 年,Fowler 开创了一个叫 bliki 的格式——blog + wiki 的混合体。 普通博客是按时间线排列的,文章写完了就固定了。Wiki 是围绕主题组织的,可以持续更新。Bliki 试图结合两者:每篇文章围绕一个概念展开,像 wiki 词条一样精炼,但又保留作者的视角和叙事。 你去看看他的 Bliki 页面,会看到从 Architecture Decision Record 到 Microservices 再到 Technical Debt 的条目。很多我们日常挂在嘴边的术语,最早的清晰定义就出自这里。 比如 ADR(架构决策记录)——这个如今被广泛采用的实践,他那篇 2026 年 3 月的 bliki 条目就是最好的入门材料之一:简短、清晰、实用,几页纸说清楚为什么要写、怎么写、写多长。 那些改变行业的概念 这个网站是不少行业关键概念的"爆发地": Microservices(微服务) —— 2014 年,Fowler 和 James Lewis 联合撰写的那篇定义性文章,到现在还是讨论微服务时被引用最多的文献之一。“微服务是一套小型的、自治的服务,每个服务围绕业务能力构建……“这段话就是从这儿来的。 ...

May 20, 2026 · 1 min · 136 words

Hello World! 🎉

我的第一篇文章 终于把个人网站搭起来了! 接下来会在这里分享技术笔记、生活感悟和各种有趣的东西。 测试代码高亮 print("Hello, World!") console.log("Hello from Hugo!"); 测试引用 千里之行,始于足下。 — 老子 敬请期待更多内容!🚀

May 19, 2026 · 1 min · 14 words

INFP:理想主义者的内心世界

什么是 INFP? INFP(Introverted, Intuitive, Feeling, Perceiving)是 MBTI 人格类型中最具理想主义色彩的一类,常被称为 **「调停者」**或 「治愈者」。他们大约占总人口的 4% — 5%。 简单来说,INFP 是那种 内心住着一个诗人 的人。 INFP 的核心特质 🌟 丰富的内心世界 INFP 最显著的特点就是拥有极其丰富的内心世界。他们的大脑里几乎无时无刻不在上演着故事、对话和想象。这种内在的丰富性让他们: 天生擅长创作 — 写作、音乐、绘画都很适合 具备极强的共情能力,能敏锐感知他人的情绪 常常陷入深度思考,对人生意义这类问题特别着迷 💭 理想主义者 INFP 追求的从来不是世俗意义上的成功。他们更关心的是: 这件事有意义吗? 这符合我的价值观吗? 这个世界有没有变得更好一点点? 他们很难为了钱或地位去做违背内心的事。这也是为什么很多 INFP 在职场中会感到格格不入。 🌱 追求真实 INFP 极度厌恶虚伪。他们能像雷达一样感知到不真诚的人和事。在社交中,INFP 可能看起来很安静,但那是因为他们只对深度连接感兴趣,受不了表面的客套和闲聊。 INFP 的优势 1. 共情能力一流 — 他们是天然的倾听者,朋友有烦恼时第一个想到的就是他们。 2. 创造力爆棚 — 无论是写代码、写文章还是画画,INFP 总能想出别人想不到的点子。 3. 价值观驱动 — 当 INFP 找到了自己相信的事情,他们会爆发出惊人的毅力和热情。 4. 包容开放 — 他们很少judge别人,尊重每个人做自己的权利。 INFP 的困境 说实话,做一个 INFP 并不容易。 😔 理想与现实的冲突 这是 INFP 人生中最大的课题。他们想要改变世界,但这个世界常常不按他们的理想运转。这种落差带来的挫败感是持续性的。 ...

May 19, 2026 · 1 min · 128 words

读《Thoughts on Slowing the Fuck Down》—— 慢下来,你才能掌控代码

原文: Thoughts on Slowing the Fuck Down — Mario Zechner 发表于 2026 年 3 月 25 日 这是一篇让人读着读着就想拍桌子的文章。 不是因为赞同,而是因为每一段话都在刺痛那些我们都经历过、却假装没看见的东西。 我们都曾以为自己是例外 如果你用过 Cursor、Claude 或任何 AI 编码工具写过一个完整项目,你大概曾经有过这个念头: “这东西效率太高了,我完全可以靠它十倍速产出。” 然后你继续写。一个文件接一个文件。agent 帮你搭架构、写接口、补测试——你像个乐队指挥一样,坐镇中央,挥一挥手就有一排排代码涌现。 你觉得自己是个天才管理者和一名高效产出者。 但作者告诉你一个残酷的事实:你只是把复杂性推迟了。 代理的问题,不是犯错,而是不会学习 文章里有一个比喻很妙:人类也会犯错,但人犯错之后会学习、会痛、会改。如果加班写出一堆屎山代码,半夜两点你会对着屏幕骂自己。 AI agent 不会。它不会痛。 同样的错误,它可以犯一千次,每次都用最新的热情把代码写得更烂一点。因为它的每次调用都是独立的——它没有记忆,没有懊悔,没有「我刚把这段逻辑搞砸了,这次不能再这样」的自我修正。 更致命的是:人类是瓶颈,这恰恰是好事。 一个人一天最多写几百行高质量代码。但一个 agent 可以在几小时内输出两万行。如果人写了烂代码,一天积累的烂东西有限。但如果一个 agent 军团在疯狂输出,那些「无害的小错误」会以指数级的速度叠加,直到有一天你回过头来发现——整个代码库已经没有一块你信任的地方了。 那种「一切都还可控」的幻觉 读这篇文章时,最击中的是这句: You let them run free, and they are merchants of complexity. 我回想了一下过去写的一些 AI 辅助项目。是的,那些代码库确实变得很奇怪。到处都是「看上去像那么回事但总觉得哪里不对劲」的抽象层。有为了一个简单的 CRUD 封装了三层接口的,有在同一段逻辑里同时用了三种设计模式的。 你不敢改,因为看不懂它是怎么拼起来的。你怕一改全崩。 agent 替你搭建了一个自己也不理解的迷宫,而你发现你才是那个被困在里面的人。 那应该怎么办? 作者的建议不是「别用 AI」,而是慢下来。 这听起来可能是整篇文章里最不性感的建议。没有奇技淫巧,没有很酷的 prompt 模板,也没有所谓的人机协作黄金法则。就是: 慢。下。来。 架构自己画,不要丢给 agent API 设计自己写,agent 可以帮你补实现 设一个每天可接受的 agent 代码量上限——和你自己能真正 review 的能力匹配 该手写就手写,手写带来的摩擦感恰恰是你理解系统的过程 这就像做饭。你可以用预制菜十分钟做出一桌菜,但你永远不会知道食材在锅里发生的变化。有些感觉,跳过了就跳过了,不会再回来。 ...

May 19, 2026 · 1 min · 154 words