讲师中心 微信公众号
AI工具推荐 视频效率加速

如何正确缓存 Promise 以避免重复请求

老强姑娘_1118

老强姑娘_1118

发布时间:2026-07-10 17:43:43

|

494人浏览过

|

来源于php中文网

原创

如何正确缓存 Promise 以避免重复请求

本文详解在 angular 等异步环境中缓存 promise 的核心原理与实践方案,重点解决因并发调用导致缓存失效、重复请求第三方 api 的问题,并提供顺序执行与去重预加载两种高效解决方案。

本文详解在 angular 等异步环境中缓存 promise 的核心原理与实践方案,重点解决因并发调用导致缓存失效、重复请求第三方 api 的问题,并提供顺序执行与去重预加载两种高效解决方案。

在实际开发中,当多个 UI 组件或数据行(如表格列表)频繁请求同一用户 ID 的数据时,若未妥善处理 Promise 缓存逻辑,极易触发重复 HTTP 请求——即使缓存服务已存在对应值,仍会因并发调用时机错位而“错过”缓存命中。根本原因在于:forEach 是同步遍历,不会等待内部的 Promise 完成,导致所有 getUser(userId) 几乎同时发起,此时缓存尚未写入,每次均穿透至第三方 API。

✅ 正确做法一:顺序执行(适用于依赖严格时序或需逐条处理响应的场景)

使用 for...of + await 确保请求串行化,天然规避竞态:

// ✅ 推荐:顺序执行,保证缓存写入后才发起下一次查询
for (const row of data) {
  try {
    const user = await this.getUser(row.userId);
    // ✅ 此时 user 必然来自缓存(第二次起)或首次请求结果
    this.processUser(row, user);
  } catch (error) {
    console.error(`Failed to fetch user ${row.userId}`, error);
  }
}

对应修正后的 getUser 方法(移除冗余 async/await,避免 Promise 构造反模式):

getUser(userId: number): Promise<any> {
  const cached = this.cacheService.get(userId);
  if (cached) {
    return Promise.resolve(cached); // 直接返回已解析的 Promise
  }

  // 发起真实请求并缓存结果
  return this.THIRDPARTYAPI.getUser(userId)
    .then(user => {
      this.cacheService.put(user.id, user);
      return user;
    });
}

⚠️ 注意:new Promise(async (resolve) => { ... }) 属于反模式——async 回调无法被 resolve 正确捕获异常,且增加不必要的嵌套。应直接链式调用 .then() 或 async/await 在调用层。

✅ 正确做法二:批量去重 + 预加载(推荐用于高性能、高复用场景)

当 data 中存在大量重复 userId 时,最优解是先提取唯一 ID,统一请求并填充缓存,再遍历消费:

// ✅ 高效:一次去重 + 并发预加载,最大化缓存命中率
const uniqueUserIds = [...new Set(data.map(row => row.userId))];
const userPromises = uniqueUserIds.map(id => this.getUser(id));

try {
  const users = await Promise.all(userPromises);
  const userMap = new Map(users.map(u => [u.id, u]));

  // ✅ 此时所有 getUser() 调用均命中缓存
  data.forEach(row => {
    const user = userMap.get(row.userId);
    if (user) {
      this.processUser(row, user);
    }
  });
} catch (error) {
  console.error('Failed to preload users', error);
}

? 关键原则总结

  • 缓存本质是状态共享:Promise 本身可被多次 .then() 订阅,因此「缓存 Promise 实例」比「缓存结果值」更优(避免重复 resolve);
  • 避免 forEach + Promise 组合:它不提供并发控制,永远是“火球式”并发;
  • 优先 Promise.all + 去重:对重复 ID 场景吞吐量最高;
  • 慎用 await 在循环中:虽能解决问题,但牺牲了并发收益;仅在业务逻辑强依赖前序结果时选用。

通过合理设计缓存策略与调用方式,即可在不修改第三方库的前提下,显著降低网络开销,提升应用响应性能与用户体验。

热门AI工具

更多
WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

LibLibAI
LibLibAI Hot

一款AI视频创作工具,主要用于国内领先的AI创意平台,以海量模型、低门槛操作与“创作-分享-商业化”生态,让小白与专业创作者都能高效实现图文乃至视频创意表达,适合需要提升相关任务效率的用户。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

相关专题

更多
promise的用法
promise的用法

“promise” 是一种用于处理异步操作的编程概念,它可以用来表示一个异步操作的最终结果。Promise 对象有三种状态:pending(进行中)、fulfilled(已成功)和 rejected(已失败)。Promise的用法主要包括构造函数、实例方法(then、catch、finally)和状态转换。

3960

2023.10.12

html文本框类型介绍
html文本框类型介绍

html文本框类型有单行文本框、密码文本框、数字文本框、日期文本框、时间文本框、文件上传文本框、多行文本框等等。详细介绍:1、单行文本框是最常见的文本框类型,用于接受单行文本输入,用户可以在文本框中输入任意文本,例如用户名、密码、电子邮件地址等;2、密码文本框用于接受密码输入,用户在输入密码时,文本框中的内容会被隐藏,以保护用户的隐私;3、数字文本框等等。

3163

2023.10.12

Buffalo框架数据库开发全教程
Buffalo框架数据库开发全教程

本专题围绕Buffalo框架数据库开发,讲解database.yml多环境配置、soda与fizz迁移生成回滚、模型结构体标签、增删改查与条件查询、一对多与多对多关联、数据校验、回调钩子、事务处理及原生SQL执行能力。

20

2026.09.23

Buffalo框架路由与请求处理实操指南
Buffalo框架路由与请求处理实操指南

本专题讲解Buffalo框架路由与请求处理机制,涵盖路由注册与分组、资源路由、Handler编写规范、Context上下文方法、参数绑定、中间件编写挂载、Session与Cookie读写、Flash消息及错误页面定制方法。

0

2026.09.23

Buffalo框架零基础入门教程
Buffalo框架零基础入门教程

本专题整理Buffalo框架入门内容,涵盖Go环境准备、buffalo CLI安装、新项目生成、目录结构说明、dev热加载启动、数据库连接配置与常见报错排查,帮助新手按约定优于配置的思路跑通第一个Buffalo框架应用。

0

2026.09.23

Conan创建软件包配方指南
Conan创建软件包配方指南

本专题介绍通过conanfile.py创建软件包的方法,讲解包名、版本、依赖和构建设置等基础信息,以及source、build、package、package_info等常用方法的作用及编写思路。

0

2026.09.22

Conan二进制包配置指南
Conan二进制包配置指南

本专题介绍Conan根据操作系统、编译器、架构和构建类型生成二进制包的方法,讲解Profile、Settings、Options及Package ID的作用,帮助管理不同平台和编译环境下的包版本。

20

2026.09.22

Conan私有仓库搭建教程
Conan私有仓库搭建教程

本专题系统的讲解Conan私有仓库的搭建流程,涵盖仓库服务部署、存储目录配置、用户认证、权限划分和远程地址添加,并介绍内部C++依赖包的上传、下载及版本维护方法。

0

2026.09.22

loomy官网入口地址合集
loomy官网入口地址合集

本专题汇总了 Loomy 桌面 AI 助理的官方入口地址合集及使用指南。提供 macOS 与 Windows 客户端下载 。Loomy 是讯飞推出的桌面级 AI 工作搭子,支持文件整理、数据分析、网页操作及通过飞书/钉钉远程操控电脑,助你高效完成本地办公任务 。

0

2026.09.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn