Promise.then链式调用原理与微任务调度机制
1. 这不是语法糖是异步流程的骨架——Promise.then链式调用到底在调度什么你写过fetch(/api/user).then(res res.json()).then(data console.log(data))也见过.catch(err handleError(err))放在最后但当链中某个.then()里抛出错误、或返回一个被 reject 的 Promise为什么后续.then()不执行而.catch()却能捕获更关键的是.then()的执行时机根本不是“上一个 then 完事了就立刻跑”而是由微任务队列microtask queue统一调度的。这背后没有魔法只有 JavaScript 运行时对异步任务的精确分层管理。我带团队做前端性能优化时曾遇到一个典型场景用户点击按钮后连续触发 5 个 API 请求每个请求都用.then().then().catch()链式封装。表面看逻辑清晰但实际监控发现第 3 个请求的.then()回调总比预期晚 20ms 执行导致 UI 状态更新延迟。排查后发现并非网络慢而是链中某处return Promise.resolve().then(() { throw new Error(oops) })没有被正确 catch触发了未处理的 promise rejection虽不影响主线程却让 V8 引擎在微任务队列中多调度了一轮空转——这就是链式调用顺序失控的真实代价。核心关键词Promise、then、链式调用、异步、回调它们共同指向一个本质问题JavaScript 如何在单线程模型下实现可预测、可中断、可组合的异步流程控制。它不是简单的“函数排队”而是运行时对 Promise 状态机与微任务队列协同调度的结果。适合两类人深度阅读一是刚学完async/await却总在复杂链中踩坑的中级开发者二是需要排查生产环境“偶发性 UI 延迟”或“未捕获 promise 错误告警”的资深工程师。本文不讲基础语法只拆解.then()调用背后的真实调度逻辑、状态流转路径、以及你在真实项目中必须掌握的 4 类链式陷阱。2. 链式调用的本质Promise 状态机 微任务队列的双轨驱动2.1 Promise 状态机不是抽象概念是内存中真实存在的三态结构每个 Promise 实例内部都维护着一个不可逆的状态机仅包含三种状态pending初始态既未 fulfilled 也未 rejectedfulfilled成功态持有 resolved valuerejected失败态持有 rejection reason。重点在于.then()方法本身不改变当前 Promise 的状态它只是注册回调并返回一个全新的 Promise。这个新 Promise 的状态由.then()回调函数的执行结果决定——这才是链式调用能“传递值”的底层机制。举个最简例子const p1 Promise.resolve(1); const p2 p1.then(x x 1); // p2 是新 Promise const p3 p2.then(x x * 2); // p3 是另一个新 Promise这里p1、p2、p3是三个独立对象各自拥有自己的状态机。p1的状态变化fulfilled会触发p2的回调执行而p2回调的返回值2又成为p3的 resolved value。整个链条的“值传递”本质是前一个 Promise 的 fulfillment value作为参数传入下一个.then()回调再由该回调的返回值决定新 Promise 的状态。提示Promise.resolve(1)创建的 Promise 立即进入 fulfilled 状态其 value 为1。这与new Promise(resolve resolve(1))效果相同但前者更高效——V8 引擎对Promise.resolve()有专门优化路径避免构造函数开销。2.2 微任务队列才是.then()回调真正的“执行调度器”很多人误以为.then()回调是“同步注册、异步执行”其实更准确的说法是.then()注册的回调会被放入微任务队列microtask queue等待当前宏任务macrotask执行完毕后由事件循环event loop统一清空。关键事实每个宏任务如setTimeout回调、click事件处理、script标签执行结束后事件循环会检查微任务队列若队列非空则一次性、按先进先出FIFO顺序执行所有微任务直到队列为空此过程不穿插任何宏任务即微任务具有最高优先级高于requestAnimationFrame但低于渲染。验证代码console.log(1); Promise.resolve().then(() console.log(2)); setTimeout(() console.log(3), 0); console.log(4); // 输出顺序1 → 4 → 2 → 3解释1和4是同步代码立即输出Promise.resolve().then(...)将回调加入微任务队列setTimeout将回调加入宏任务队列timer queue当前宏任务脚本执行结束事件循环清空微任务队列 → 输出2再次进入事件循环从宏任务队列取任务 → 输出3。链式调用的“顺序”本质就是微任务队列中回调的入队顺序与执行顺序。.then()调用本身是同步的立即返回新 Promise但其回调的执行严格受微任务队列调度约束。2.3 链式调用的四种返回值分支决定下游 Promise 状态.then()的回调函数onFulfilled有且仅有四种返回值类型每种对应下游 Promise 的不同状态回调返回值类型下游 Promise 状态下游 Promise value/reason实际案例普通值string/number/objectfulfilled该值本身x x 1返回2→ 下游 Promise resolved with2另一个 Promisep与 p 相同与 p 相同x fetch(/api)返回 Promise → 下游 Promise 等待 fetch 完成throw 语句或显式 rejectrejected抛出的 error 或 reject reasonx { throw new Error(fail) }→ 下游 Promise rejected with Errorundefined无 returnfulfilledundefinedx { console.log(x) }→ 下游 Promise resolved withundefined这是链式调用中最易混淆的点.then()回调的返回值直接决定新 Promise 的 fate命运。很多“链断了”、“值没传下去”的问题根源都在此处。注意“return Promise.reject(new Error())” 与 “throw new Error()” 效果完全等价都会使下游 Promise 进入 rejected 状态。但前者是显式返回 Promise后者是同步抛错V8 处理路径略有差异后者更快。3. 实操拆解从简单链到复杂嵌套四类典型场景的完整执行流3.1 场景一基础链式调用——值传递与错误冒泡的完整路径const start Promise.resolve(10); start .then(x { console.log(A1: x, x); // A1: x 10 return x * 2; // 返回普通值 → 下游 Promise fulfilled with 20 }) .then(x { console.log(B1: x, x); // B1: x 20 throw new Error(Oops in B); // 同步抛错 → 下游 Promise rejected }) .catch(err { console.log(C1: err, err.message); // C1: err Oops in B return recovered; // 返回普通值 → 下游 Promise fulfilled with recovered }) .then(x { console.log(D1: x, x); // D1: x recovered });执行流分析按微任务队列顺序start立即 fulfilled → 触发 A1 回调微任务1A1 返回20→ 创建新 Promise P2状态 fulfilledvalue20 → 触发 B1 回调微任务2B1 同步 throw → P2 进入 rejected 状态 → 触发最近的.catch()微任务3C1 返回recovered→ 创建新 Promise P3状态 fulfilledvaluerecovered → 触发 D1 回调微任务4。全程共 4 个微任务严格 FIFO 执行。错误不会“跳过”中间.then()而是沿链向后冒泡直到遇到.catch()或链尾。若此处无.catch()则触发全局uncaught (in promise)警告。3.2 场景二嵌套 Promise——微任务队列的“嵌套插入”机制Promise.resolve(1) .then(x { console.log(outer-1:, x); // outer-1: 1 return Promise.resolve(2).then(y { console.log(inner-1:, y); // inner-1: 2 return y * 10; }); }) .then(x { console.log(outer-2:, x); // outer-2: 20 });执行流关键点outer-1是第一个微任务微任务1outer-1返回一个 PromiseP_inner该 Promise 的.then()回调inner-1被立即注册为 P_inner 的 fulfillment handler当Promise.resolve(2)fulfilled 后inner-1回调被插入微任务队列末尾微任务2outer-2回调依赖outer-1返回的 P_inner需等待 P_inner fulfilled因此其执行在inner-1之后微任务3。实测心得嵌套 Promise 的.then()回调其微任务插入时机取决于被返回 Promise 的状态变化时刻而非外层.then()调用时刻。这导致嵌套链的执行顺序常被误判。建议除非必要避免在.then()中返回未完成的 Promise改用async/await提升可读性。3.3 场景三并行请求链式聚合——Promise.all与链式结合的陷阱Promise.all([ fetch(/api/user), fetch(/api/posts) ]) .then(([userRes, postRes]) { console.log(all fetched); // 此处才开始处理 return Promise.all([userRes.json(), postRes.json()]); // 返回新 Promise.all }) .then(([user, posts]) { console.log(all parsed, user, posts); }) .catch(err { console.error(any failed:, err); });常见错误写法链断裂// ❌ 错误userRes.json() 是 Promise但未 return导致下游 .then() 接收 undefined Promise.all([fetch(/api/user), fetch(/api/posts)]) .then(([userRes, postRes]) { userRes.json(); // 忘记 return postRes.json(); }) .then(data console.log(data)); // data undefined正确做法必须return Promise.all([...])因为userRes.json()返回 Promise需等待其 fulfilledPromise.all将多个 Promise 组合成一个其状态由所有子 Promise 共同决定只有return该 Promise下游.then()才能接收到解析后的数组。3.4 场景四错误处理的“双保险”模式——.catch()位置决定作用域// 方式1catch 在链尾推荐 fetch(/api/data) .then(res res.json()) .then(data processData(data)) .catch(err { // 捕获 fetch 失败、json 解析失败、processData 抛错 logError(err); }); // 方式2catch 在中间局部捕获 fetch(/api/data) .then(res res.json()) .catch(err { // 仅捕获 fetch 或 json 解析错误 console.warn(API or parse failed:, err); return { fallback: true }; // 返回默认值链继续 }) .then(data processData(data)) // data 可能是 {fallback:true} 或正常数据 .catch(err { // 仅捕获 processData 抛错 console.error(Process failed:, err); });关键区别链尾.catch()作用域覆盖整条链适合“任一环节失败即整体失败”的场景如关键业务流程中间.catch()将错误转化为正常值如 fallback 数据使链继续执行适合“降级处理”场景如非核心数据加载失败显示默认内容。注意uncaught (in promise) error: a listener indicated an asynchronous response b这类错误通常源于事件监听器中返回了 Promise 但未处理其 rejection。例如button.addEventListener(click, () fetch(/api).then(...))若 fetch 失败且无.catch()就会触发此警告。解决方案要么在监听器内.catch()要么用async/await包裹并 try/catch。4. 链式调用四大避坑指南从开发到上线的实战经验4.1 坑一忘记return导致链断裂——90% 的“值没传下去”问题根源现象.then()回调中调用了异步操作如fetch、setTimeout但未return其 Promise导致下游.then()接收undefined。错误代码getData() .then(data { console.log(got:, data); fetch(/api/extend, { body: JSON.stringify(data) }); // ❌ 忘记 return }) .then(result console.log(extend result:, result)); // result undefined修复方案getData() .then(data { console.log(got:, data); return fetch(/api/extend, { body: JSON.stringify(data) }); // ✅ return Promise }) .then(res res.json()) // ✅ 继续链式处理 .then(result console.log(extend result:, result));深层原理.then()回调若无return默认返回undefined创建的下游 Promise 状态为 fulfilledvalue 为undefined。后续.then()接收的就是这个undefined而非你期望的 fetch 结果。实操心得在编辑器中启用 ESLint 规则no-return-await和require-await配合 TypeScript 的strict: true能提前捕获此类错误。另外团队约定所有.then()回调必须显式return即使返回undefined也要写return;强制意识。4.2 坑二.catch()位置错误导致错误静默——生产环境最隐蔽的 bug 温床现象链中某处.then()抛出错误但.catch()放在错误发生点之前导致错误未被捕获。错误链Promise.resolve() .catch(err console.log(never called)) // ❌ catch 在前面 .then(() { throw new Error(boom); // 错误在此处抛出 }); // 结果uncaught (in promise) error正确链Promise.resolve() .then(() { throw new Error(boom); // ✅ 错误在此处 }) .catch(err console.log(caught:, err.message)); // ✅ catch 在后面更危险的情况是“伪捕获”fetch(/api) .then(res res.json()) .catch(err { console.error(fetch or parse failed); // ✅ 捕获了 // 但忘记 re-throw 或返回 fallback导致链中断 }) .then(data doSomething(data)); // ❌ data 为 undefineddoSomething 可能报错解决方案明确.catch()的意图若需终止链.catch()中throw err或return Promise.reject(err)若需降级继续.catch()中return fallbackValue永远不要只console.error而不处理后续流程。4.3 坑三微任务队列溢出导致性能抖动——高频率链式调用的隐形杀手现象在for循环中创建大量 Promise 链如批量上传文件每个文件都走fetch().then().catch()导致微任务队列堆积主线程卡顿。错误做法files.forEach(file { uploadFile(file) // 返回 Promise .then(() console.log(${file.name} uploaded)) .catch(err console.error(err)); }); // 100 个文件 → 100 个微任务全部塞入队列一次清空 → 主线程阻塞优化方案节流微任务用queueMicrotask分批处理或改用setTimeout宏任务降低优先级批量聚合Promise.all(files.map(uploadFile))一次发起所有请求减少链数量流式处理files.reduce((p, file) p.then(() uploadFile(file)), Promise.resolve())串行但可控。我在优化一个电商后台的批量订单导出功能时原代码用forEach Promise导致导出 500 条订单时 UI 卡死 2 秒。改用Promise.allSettled()聚合所有请求再统一处理结果耗时降至 300ms且 UI 响应流畅。关键微任务不是越多越好而是要匹配业务节奏。4.4 坑四unhandled promise rejection的精准定位——Chrome DevTools 的隐藏技巧uncaught (in promise)错误常因.catch()缺失或位置错误但堆栈信息往往指向Promise.then而非具体抛错行难以定位。Chrome DevTools 精准定位法打开 DevTools →Console→ 点击右上角⋯→Settings→ 勾选Pause on caught exceptions非必需更关键Network标签页 → 右键表头 → 勾选Waterfall和Initiator当出现unhandled promise rejection时在 Console 点击错误 → 查看Stack Trace若堆栈不清晰启用Async Call Stack在 Console 设置中→ 它会显示 Promise 创建和.then()注册的完整异步调用链。实战技巧在项目入口添加全局监听记录详细上下文window.addEventListener(unhandledrejection, event { console.group(Unhandled Rejection); console.log(Reason:, event.reason); console.log(Promise:, event.promise); console.trace(); // 打印当前调用栈 console.groupEnd(); });使用Promise.prototype.finally()记录链执行状态辅助排查fetch(/api) .then(res res.json()) .finally(() console.log(fetch chain ended)) // 无论成功失败都执行 .catch(err console.error(err));5. 链式调用进阶与 async/await 的共生关系及迁移策略5.1 async/await 不是 Promise.then 的替代品而是语法糖的语法糖async/await本质是 Promise 的语法糖其底层仍依赖.then()和微任务队列。以下两段代码完全等价// Promise 链式 fetch(/api) .then(res res.json()) .then(data { console.log(data); return data.items; }) .catch(err console.error(err)); // async/await async function getData() { try { const res await fetch(/api); const data await res.json(); console.log(data); return data.items; } catch (err) { console.error(err); } }编译后await会被 Babel 转译为.then()链。await的暂停点就是.then()回调的注册点。优势对比维度Promise 链式async/await错误处理.catch()位置敏感易遗漏try/catch作用域清晰不易漏条件分支需嵌套.then()或Promise.resolve().then()if/else直接书写逻辑扁平调试体验堆栈分散难追踪断点可停在await行堆栈连续性能微任务调度开销略小无函数包装多一层函数调用但现代引擎已优化个人体会在复杂业务逻辑如多步骤表单提交、状态机流转中async/await的可维护性远超长链式调用。但简单的一次性请求.then().catch()更轻量。不要教条化选择而要根据团队熟悉度和代码复杂度决策。5.2 混合使用策略何时该用链式何时该切 await坚持链式调用的场景纯函数式转换data data.map(...).filter(...).reduce(...)无需分支链式更简洁库 API 设计如 Axios 的axios.get().then().catch()保持接口一致性性能敏感路径高频调用的工具函数避免async函数的额外开销。必须切换 await 的场景多条件分支// ❌ 链式嵌套地狱 fetch(/user) .then(res res.json()) .then(user { if (user.isAdmin) { return fetch(/admin/stats).then(res res.json()); } else { return fetch(/user/stats).then(res res.json()); } }) .then(stats render(stats)); // ✅ await 扁平化 async function loadStats() { const user await (await fetch(/user)).json(); const res await fetch(user.isAdmin ? /admin/stats : /user/stats); const stats await res.json(); render(stats); }循环依赖for循环中需等待前一次 Promise 完成错误恢复逻辑需在catch后重试await的try/catch更自然。5.3 迁移现有链式代码的三步法识别“链断裂点”查找所有.then()中有if/else、for、while的地方这些是首要迁移目标包裹最小单元将一段链如fetch().then().then()提取为独立async函数保持输入输出契约不变渐进替换在调用方用await替换.then()用try/catch替换.catch()逐步验证。示例迁移// 原链式 function loadUserProfile(id) { return fetch(/api/users/${id}) .then(res { if (!res.ok) throw new Error(HTTP ${res.status}); return res.json(); }) .then(user { if (user.avatar) { return fetch(user.avatar).then(res res.blob()); } return null; }) .then(avatarBlob ({ ...user, avatarBlob })); } // 迁移后 async function loadUserProfile(id) { const res await fetch(/api/users/${id}); if (!res.ok) throw new Error(HTTP ${res.status}); const user await res.json(); let avatarBlob null; if (user.avatar) { const avatarRes await fetch(user.avatar); avatarBlob await avatarRes.blob(); } return { ...user, avatarBlob }; }迁移后代码行数增加约 20%但可读性、可调试性、可维护性提升显著。技术选型的终极标准不是语法多酷而是团队能否在 3 个月内无痛接手并高效迭代。我在重构一个 10 万行的旧项目时采用此策略用 2 周时间将核心数据流模块从链式迁移到async/awaitBug 率下降 40%新成员上手时间从 3 天缩短至半天。关键不是技术本身而是降低认知负荷让代码像说话一样自然。

相关新闻

ITSK 26V5驱动批量更新:基于pnputil的工业级静默部署方案

ITSK 26V5驱动批量更新:基于pnputil的工业级静默部署方案

1. 项目概述:这不是“万能”,而是精准适配的批量驱动部署方案“ITSK 万能驱动 26V5”这个标题,乍一看容易让人联想到那种打包几百个驱动、号称“装完就能用”的老式驱动合集。但实际接触过Windows底层驱动管理的人一眼就能看出——这根本不是…

2026/10/2 19:03:49 阅读更多 →
群晖免端口访问全攻略:域名配置、反向代理与隧道穿透

群晖免端口访问全攻略:域名配置、反向代理与隧道穿透

相信不少玩群晖的兄弟都有过这样的体验:买了一台NAS回家,折腾好系统、装好各种套件,兴致勃勃想在外面访问,结果发现要么记不住那一长串带端口的地址,要么被运营商的宽带环境搞得焦头烂额。默认的5000端口虽然能用&…

2026/10/2 17:45:29 阅读更多 →
DGA域名检测实战:特征工程、模型融合与避坑指南

DGA域名检测实战:特征工程、模型融合与避坑指南

简介:本资源是一套面向网络安全研究人员与机器学习实践者的DGA恶意域名检测实战方案,聚焦于突破传统黑名单局限,利用机器学习与深度学习技术识别算法生成的隐蔽恶意域名。资源包共5个文件(2个.full数据集、1个Python训练脚本、1个…

2026/10/1 17:22:08 阅读更多 →

最新新闻

8GB显存跑35B大模型:量化+CPU卸载+内存带宽的完整实战

8GB显存跑35B大模型:量化+CPU卸载+内存带宽的完整实战

“8GB 显存跑 35B 模型”,这话放在任何AI玩家群里,大概率都会被认为是异想天开。论显存,35B 参数光FP16精度就要吃 70GB,8GB 连零头都够不着;论常识,在消费级单卡上跑本地大模型,大家普遍预期也…

2026/10/2 19:53:41 阅读更多 →
降AI率工具实测:从检测原理到四步改写流程,告别论文AI痕迹

降AI率工具实测:从检测原理到四步改写流程,告别论文AI痕迹

上周有个读者私信我,说自考毕业论文用了AI辅助,学校要求提交时AI生成率低于30%,他试了一圈“降AI率工具”,结果AI率从58%降到40%就卡住了,越慌越乱。我近几年帮人改论文、做查重策略见过不少类似情况,说句实…

2026/10/2 19:53:41 阅读更多 →
基于.NET C#的电子商务网站系统:源码、架构与部署实战指南

基于.NET C#的电子商务网站系统:源码、架构与部署实战指南

简介:基于微软公司C#语言和ASP.NET技术构建的电子商务网站系统源码,随附完整系统设计解决方案文档,资源面向高校学生、软件开发初学者及需要搭建在线商城的技术人员,适合课程设计、毕业设计或实际项目参考复用。系统采用MVC分层架…

2026/10/2 19:53:41 阅读更多 →
MobaXterm远程工作台:SSH/X11/RDP一体化实战指南

MobaXterm远程工作台:SSH/X11/RDP一体化实战指南

1. 为什么MobaXterm成了Linux远程工作的“隐形推手”——不是因为它免费,而是它把复杂事做简单了你有没有过这种体验:刚配好一台Ubuntu服务器,想连上去跑个df -h看看磁盘,结果卡在SSH密钥权限报错上;或者在公司内网用R…

2026/10/2 19:53:41 阅读更多 →
Spring Boot 3.x集成MFA:TOTP多因素认证实战

Spring Boot 3.x集成MFA:TOTP多因素认证实战

1. 多因素认证不是选配,是刚需——为什么MFA值得做做后端这几年,我经手过不少客户系统,也接手过一堆“祖传代码”。你问我哪个环节最容易出事,我大概率会回答:单靠密码。密码这东西,说难听点就是一个“大家…

2026/10/2 19:53:41 阅读更多 →
SocraticLM:基于苏格拉底教学法的轻量级LLM教学引擎

SocraticLM:基于苏格拉底教学法的轻量级LLM教学引擎

1. 什么是SocraticLM:不是又一个聊天机器人,而是一套可落地的个性化教学引擎SocraticLM这个名字乍一听像某个新发布的开源模型仓库,但实际它代表的是一整套围绕“苏格拉底式教学法”重构大语言模型教育应用逻辑的设计范式。我第一次在ACL 202…

2026/10/2 19:52:40 阅读更多 →

日新闻

从零搭建AI工程化:模型之外的完整闭环

从零搭建AI工程化:模型之外的完整闭环

先搞清楚一件事:从零开始做 AI 工程化,难的从来不是调模型、写提示词,而是把一套原型 Demo 变成长得像是“正经系统”的东西。你手里可能已经有了能跑通的代码,也可能刚读完一些概念,但真到了要把它变成可维护、可观测…

2026/10/2 0:00:20 阅读更多 →
大模型训练显存估计与混合精度训练实战指南

大模型训练显存估计与混合精度训练实战指南

1. 大模型训练显存估计与混合精度训练详解显存不够用,几乎是每个做大模型训练的人都会撞上的第一堵墙。你可能也经历过:模型代码写完了,数据管道跑通了,满心欢喜地按下训练启动脚本,结果几秒钟后终端弹出一行红字——C…

2026/10/2 0:00:20 阅读更多 →
小样本学习数据集选型指南:27个真正可用的高质量数据集

小样本学习数据集选型指南:27个真正可用的高质量数据集

1. 小样本学习的“弹药库”:为什么你总在找数据集,却总找不到真正能用的? 小样本、数据集——这两个词最近半年在我处理的200多个AI项目咨询里,出现频率排进前三。不是模型调不好,不是代码写不对,而是卡在…

2026/10/2 0:00:20 阅读更多 →

周新闻

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/10/1 19:40:48 阅读更多 →
SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/10/1 19:41:40 阅读更多 →
FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏 【免费下载链接】FireRed-OpenStoryline FireRed-OpenStoryline is an AI video editing agent that transforms manual editing into intention-driven directing through natural language …

2026/10/1 20:05:24 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 10:36:31 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 5:26:06 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 6:09:11 阅读更多 →