声明为async的函数仍报“无法在async函数外使用await关键字”错误的原因
问题原因分析
你遇到的这个问题其实很常见——虽然外层的getData()确实声明成了async函数,但你在forEach的回调函数里使用了await,而这个回调函数本身并没有被标记为async。
JavaScript的async特性是函数级别的,只有当await所在的直接函数被声明为async时,它才能被合法使用。你这里的await是写在Object.entries(menu).forEach(o => { ... })这个箭头函数里的,这个箭头函数并没有async修饰,所以JS引擎会认为你在非async函数里用了await,自然就抛出错误了。
解决方案
有两种常见的修复方式,你可以根据需求选择:
方式一:使用for...of循环替代forEach
这种方式最直观,也不需要处理异步并行的问题:
async getData() { // 此处已有其他await操作 const menu = { 'pounds': 'DemandModification', 'combination': 'DemandCombinationOverride' }; const overridesWithStaleBuckets = {}; // 用for...of遍历entries for (const [overrideType, api] of Object.entries(menu)) { const overrides = await this.$http.execute('read', api); overridesWithStaleBuckets[overrideType] = overrides; } // 省略无问题逻辑 return overridesWithStaleBuckets; }
这种方式会按顺序执行每个异步请求,前一个请求完成后才会发起下一个。
方式二:将forEach的回调改为async,并使用Promise.all处理并行
如果你希望所有异步请求同时发起(并行执行),可以用这种方式:
async getData() { // 此处已有其他await操作 const menu = { 'pounds': 'DemandModification', 'combination': 'DemandCombinationOverride' }; // 收集所有异步任务 const tasks = Object.entries(menu).map(async ([overrideType, api]) => { const overrides = await this.$http.execute('read', api); return { overrideType, overrides }; }); // 等待所有任务完成 const results = await Promise.all(tasks); // 组装结果对象 const overridesWithStaleBuckets = {}; results.forEach(({ overrideType, overrides }) => { overridesWithStaleBuckets[overrideType] = overrides; }); // 省略无问题逻辑 return overridesWithStaleBuckets; }
注意:forEach本身不会等待异步回调完成,所以直接给forEach的回调加async的话,外层函数会直接继续执行后面的代码,不会等所有异步操作完成。因此需要用map收集所有Promise,再用Promise.all等待全部完成。
内容的提问来源于stack exchange,提问作者knot22
相关产品推荐
相关产品推荐

