如何仅执行一次异步数据库调用并复用结果供后续函数使用?
避免重复数据库/API查询的解决方案
你当前的代码每次调用getData()都会发起新的查询,核心原因是每次执行都会重新调用await GetCoverage("all"),没有复用已获取的结果。通过添加缓存机制可以实现仅执行一次查询,后续调用直接复用结果,以下是两种实用方案:
方案一:缓存查询结果(适用于非高并发场景)
修改getData函数,先检查是否已有缓存数据,有则直接返回,无则发起请求并缓存结果:
async function GetCoverage(scroll_path) { const apiName = "xxxx"; const path = "/scrolls/" + scroll_path; const myInit = { headers: {}, response: false, }; const response = await API.get(apiName, path, myInit); console.log("response:", response); return response.Items; } let dataGlobal; const getData = async () => { // 已有缓存直接返回 if (dataGlobal) { return dataGlobal; } // 无缓存时发起请求并缓存 const response = await GetCoverage("all"); dataGlobal = response; return response; }; // 测试:多次调用仅触发一次请求 (async () => { const res1 = await getData(); const res2 = await getData(); console.log(res1 === res2); // 输出true,复用同一数据 })();
方案二:缓存请求Promise(处理并发场景)
如果存在多个地方同时调用getData()的情况,方案一可能会在首次请求未完成时触发重复请求。此时可以缓存请求的Promise,确保并发调用复用同一个请求:
async function GetCoverage(scroll_path) { const apiName = "xxxx"; const path = "/scrolls/" + scroll_path; const myInit = { headers: {}, response: false, }; const response = await API.get(apiName, path, myInit); console.log("response:", response); return response.Items; } let dataPromise; // 缓存请求的Promise对象 const getData = async () => { // 已有Promise直接复用 if (dataPromise) { return dataPromise; } // 发起请求并缓存Promise dataPromise = GetCoverage("all"); try { const result = await dataPromise; return result; } catch (err) { // 请求失败时清除缓存,允许后续重试 dataPromise = null; throw err; } }; // 测试并发调用:仅触发一次请求 (async () => { const [res1, res2] = await Promise.all([getData(), getData()]); console.log(res1 === res2); // 输出true })();
方案对比
- 方案一:实现简单,适合低并发场景,但无法避免首次请求未完成时的并发重复调用。
- 方案二:更健壮,能完美处理并发场景,同时支持请求失败后的重试机制。
内容的提问来源于stack exchange,提问作者Tennis Smith
相关产品推荐
相关产品推荐

