JS函数循环内await未生效,导致重复请求外部服务问题排查
问题分析与修复
你没有正确使用await,导致异步逻辑失控,出现重复请求的问题,核心问题出在这两处:
问题根源
map中的异步函数不会阻塞流程textObj.map(async (styleData) => { ... })会直接返回一个Promise数组,但map本身不会等待这些异步操作完成。外层的for循环会继续执行,同时多个异步函数会并发运行——这时候所有请求都会同时检查_allFontSets,但还没有任何一个请求完成并写入缓存,所以全部会判定为“新字体”,发起重复请求。函数未标记为
async
你在函数内部使用了await,但updatesNodes本身没有声明为async函数,这不仅会导致语法错误,也无法让外层逻辑等待内部异步操作完成。
修复方案
修复后的代码
_allFontSets = {} async updatesNodes() { // 标记为async函数,允许内部使用await for (const [textEntity] of this._allEntities) { // 修正原代码变量名不匹配的问题 const textObj = this._allEntities.get(textEntity); // 用Promise.all等待所有异步操作完成 const ranges = await Promise.all(textObj.map(async (styleData)=> { const font = styleData.font; const stringified = JSON.stringify(font); if (this._allFontSets[stringified]) { console.log("ALREADY SEEN FONT") // 如果是加载中的Promise则等待,是已加载的字体则直接返回 return await this._allFontSets[stringified]; } else { console.log("NEW FONT") // 先把请求Promise存入缓存,避免后续重复发起请求 const fontPromise = getFont(); this._allFontSets[stringified] = fontPromise; // 等待请求完成 const loadedFont = await fontPromise; // 替换缓存为已加载完成的字体 this._allFontSets[stringified] = loadedFont; return loadedFont; } })); const data = { ranges: ranges }; // 后续处理data的逻辑... } }
关键修复点
- 给
updatesNodes添加async声明,让函数支持内部await逻辑。 - 使用
Promise.all()等待map生成的所有异步操作完成,确保字体请求处理完毕后再继续后续流程。 - 在发起请求前先将
Promise存入_allFontSets,后续相同字体的请求会直接等待这个Promise完成,彻底避免重复请求。
内容的提问来源于stack exchange,提问作者sal3jfc
相关产品推荐
相关产品推荐

