资讯动态

Comp AI CRM 前端异步依赖并行化:用 better-all 消除 Promise 瀑布流

发布时间:2026/9/24 14:57:34 来源:尧图企业网站定制
后端前端CRM人工智能AI Agent【免费下载链接】crmComp AI CRM is an open source, CRM designed for AI agents. Agentic-first CRM.项目地址https://gitcode.com/gh_mirrors/crm48/crm点击查看免费下载本篇技术指南聚焦 Comp AI CRM开源 Agentic-first CRM前端为 Next.js 16 React 19 应用在数据获取场景中的一项关键性能实践——依赖型并行化Dependency-Based Parallelization。当多个异步操作之间存在部分依赖例如 profile 依赖 user而 config 完全独立时如何避免不必要的串行等待、让每个任务在最早可行时刻启动。读完本文你将掌握better-all的用法、零依赖的 Promise-first 替代方案以及本仓库中与之配套的Promise.all()并行化规则与真实代码佐证。问题的本质Promise 瀑布流Waterfall在 React / Next.js 应用中最常见的性能杀手之一就是隐式串行等待。想象下面的代码const [user, config] await Promise.all([ fetchUser(), fetchConfig() ]) const profile await fetchProfile(user.id)从语义上看fetchUser()与fetchConfig()已经并行看似没问题。但仔细推敲时序就会发现fetchProfile(user.id)必须等 user 返回才能发起fetchProfile发起请求时fetchConfig()大概率早已完成于是config白白等待profile完成形成一次多余的串行尾巴。这就是规则文档.agents/skills/vercel-react-best-practices/rules/async-dependencies.md所指出的问题profile 为等待 config 而空转。整个请求链从理想的两跳变成了三跳。在 Comp AI CRM 这类以列表页、详情页、Agent 会话页为主的真实业务中这种模式随处可见一个页面往往同时需要会话鉴权、配置/设置项、以及依赖用户 ID 的业务数据。若放任瀑布流页面加载时间会成倍放大。方案一引入 better-all 实现依赖感知的并行规则文档给出的正解是使用 Vercel 推荐的better-all包可在 npm 上安装import { all } from better-all const { user, config, profile } await all({ async user() { return fetchUser() }, async config() { return fetchConfig() }, async profile() { return fetchProfile((await this.$.user).id) } })核心机制是all()接收一个任务对象每个字段是一个异步函数better-all会自动分析任务间的依赖通过this.$.xxx声明对其它任务的引用并在依赖就绪的第一时间启动后续任务。user与config在同一轮启动互不等待profile声明依赖user因此只在user完成后立即触发不再等config整个调用以对象形式一次性解构出全部结果代码可读性与类型安全都很好。相比手写Promise.allbetter-all的价值在于依赖链越长、分支越多收益越明显无需人工判断谁先谁后、谁可以和谁合并声明式地表达依赖关系即可自动获得最大并行度。方案二不引入依赖的 Promise-first 写法如果不想为单个场景新增第三方依赖规则文档同样给出了先创建所有 Promise、最后统一Promise.all的替代方案const userPromise fetchUser() const profilePromise userPromise.then(user fetchProfile(user.id)) const [user, config, profile] await Promise.all([ userPromise, fetchConfig(), profilePromise ])要点拆解fetchUser()在赋值那一刻立即发起不等待任何awaitprofilePromise通过.then()挂在userPromise上形成一条即时的依赖边user一落地就自动触发fetchProfile最后Promise.all一次性等待全部结果。这样config与profile天然并行效果与better-all等价且零依赖。这条路线正是 Vercel 规则中Start promises early, await late思想的直接体现规则文件见.agents/skills/vercel-react-best-practices/rules/async-api-routes.md。与相邻规则的关系一整套消除瀑布流的方法论依赖并行化并非孤立技巧它属于.agents/skills/vercel-react-best-practices/SKILL.md中Eliminating Waterfalls消除瀑布流这一优先级为 CRITICAL 的第一类规则前缀async-。该技能集共收录 70 条规则、横跨 8 个类别其中消除瀑布流排在优先级第一档标注影响为 2-10× 的提升。与async-dependencies直接相关的姊妹规则包括规则文件核心主张适用场景async-parallel完全独立的操作直接用Promise.all()并行fetchUser()、fetchPosts()、fetchComments()互不依赖async-api-routesAPI Route / Server Action 中先启动 Promise 再 awaitauth()与fetchConfig()立即发起fetchData(session.id)等会话async-defer-await把await移进真正用到的分支提前 return 的路径不再阻塞等待async-cheap-condition-before-await便宜的同步条件先判断再 await 远程 flagflag someCondition短路async-dependencies本文部分依赖时用better-all自动并行profile 依赖 user、config 独立选择逻辑可以归纳为一条决策链完全独立 →Promise.all部分依赖 →better-all或 Promise-first 链式可提前返回 → defer await条件守卫 → cheap condition first。仓库实践佐证Comp AI CRM 中的并行化真实案例这套规则在本仓库中并非纸上谈兵前端应用apps/app的多个页面和工具函数已经落地了并行化模式案例一列表页服务端并行预取在apps/app/app/(app)/[slug]/deals/page.tsx中Deals 页面将会话校验 搜索参数解析合并为一次Promise.all随后又将三个 tRPC 查询的prefetchQuery再次并行const [, values] await Promise.all([ requireSession(), dealsSearchParams.load(searchParams), ]); await Promise.all([ queryClient.prefetchQuery( trpc.deals.list.queryOptions(dealsSearchParams.toInput(values)), ), queryClient.prefetchQuery(trpc.users.list.queryOptions()), queryClient.prefetchQuery(trpc.companies.options.queryOptions({ q: })), ]);这里deals.list、users.list、companies.options彼此独立全部通过Promise.all并发发起将三次网络往返压缩为一次窗口内的并发请求。这与async-parallel规则完全一致。案例二客户端缓存失效的批量并行在apps/app/lib/trpc/cache.ts的useCrmCache()中无论是失效所有记录还是批量失效某类查询键最终都统一收敛到Promise.allreturn Promise.all( awaited.map((queryKey) queryClient.invalidateQueries({ queryKey })), ).then(() undefined);此外deals、contacts、companies等实体相关缓存操作使用了先行失效 后台静默失效settle: record时void invalidateQueries的组合避免阻塞关键路径——这正是defer await / 非阻塞执行思想的客户端版本。从源码结构看仓库对尽早并行、延迟等待这一原则的贯彻是系统性的服务端Next.js RSC 页面通过Promise.all并行 prefetch客户端通过Promise.all批量失效缓存两者共同减少了首屏与交互路径上的串行等待。使用边界与注意事项并行化并非万能规则文档与仓库实践提示以下几点边界有严格副作用顺序时不要盲目并行如果任务之间存在必须的先后副作用如先写日志再写库强行并行会破坏语义此时应保留串行。错误处理语义Promise.all是一损俱损——任一 Promise reject 即整体 reject。若希望部分失败不影响整体需要改用Promise.allSettled或better-all提供的对应错误策略。依赖复杂时优先声明式工具两三个依赖手写 Promise 链尚可当依赖图复杂多级、多分支时better-all的声明式写法可读性、可维护性明显更优且自动获得最大并行度。结合缓存去重Comp AI CRM 的 tRPC TanStack Query 架构本身具备请求去重能力并行化与缓存结合时重复请求会被自动合并见apps/app/lib/trpc/client.tsx与apps/app/lib/trpc/query-client.ts的配置进一步提升效率。总结依赖型并行化的本质是把人为编排的等待顺序交给运行时的依赖分析better-all或 Promise 链的即时绑定Promise-first去解决从而让每一跳网络请求都尽早发出。对 Comp AI CRM 这类列表/详情/Agent 会话密集的 Next.js 应用这一优化能直接压缩页面关键路径而仓库中 deals 页面/[slug]/deals/page.tsx) 的并行 prefetch 与 cache.ts 的批量失效正是这套规则在生产代码中的最佳注脚。完整的 70 条规则清单及分类优先级可查阅 vercel-react-best-practices/SKILL.md。赞分享后端前端CRM人工智能AI Agent【免费下载链接】crmComp AI CRM is an open source, CRM designed for AI agents. Agentic-first CRM.项目地址https://gitcode.com/gh_mirrors/crm48/crm点击查看免费下载相关推荐OpenMetadata 前端异步依赖并行化实战用 better-all 消除 Promise 瀑布流OpenMetadata 前端异步依赖并行化实战用 better all 消除 Promise 瀑布流 导读 在 OpenMetadata 的 React/T数据目录数据血缘数据治理后端MCP 服务Cherry Studio 中的依赖式并行化用 better-all 消除 Promise 瀑布流Cherry Studio 中的依赖式并行化用 better all 消除 Promise 瀑布流 导读 在 React / Next.js 应用以及基于AI 应用大模型桌面应用本地部署RAGSurfSense 前端性能实践基于依赖的并行化better-all消除异步瀑布SurfSense 前端性能实践基于依赖的并行化better all消除异步瀑布 本篇聚焦 SurfSense 仓库内置的 Vercel React 性能人工智能AI 应用后端AI Agent网页爬虫RAG深度研究MCP 服务前端上一篇3B参数改写企业AI规则IBM Granite-4.0-H-Micro轻量化革命下一篇Lozad.js与服务器推送HTTP/2 Server Push的协同策略创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价