You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

await仅在async函数中有效:computeAggregate无法等待fetchRecords的Promise

问题分析与修复方案

你遇到的核心问题是**await被用在了一个非async的回调函数里**,而且就算给回调加async,外层的computeAggregate也无法等待回调内的异步操作完成。咱们一步一步解决:

为什么原来的代码报错?

你在model.collection.distinct的普通回调函数里使用了await,但这个回调并没有被标记为async——JS严格要求await只能出现在async函数内部,所以直接触发报错。

更糟的是,就算你把回调改成async function(error, distMinutes) {...},外层的computeAggregate函数也不会等待这个回调里的所有异步逻辑执行完毕,因为回调是异步触发的,外层函数会直接走完流程,导致你的聚合逻辑无法按预期完成。

修复后的代码(顺序执行版本)

我们把model.collection.distinct改成Promise形式(Mongoose的大部分方法都支持Promise,不用非得用回调),然后在async函数的主逻辑里使用await,同时用for...of遍历数组(比for...in更安全,避免遍历到原型链上的属性):

const computeAggregate = async (model, sym) => { 
  try {
    // 改用Promise形式获取distinct结果,替代回调写法
    const distMinutes = await model.collection.distinct("minutes_offs", { symbol: sym });
    
    // 用for...of遍历,支持在循环内使用await顺序执行
    for (const minuteOff of distMinutes) { 
      console.log("inside minutes off", minuteOff); 
      const records = await fetchRecords(model, sym, minuteOff); 
      const aggData = getAggregateData(records); 
      createCollection(aggData); 
    }
  } catch (error) {
    console.log("error in computeAggregate", error);
  }
} 

const fetchRecords = async (model, sym, minutesOff) => { 
  console.log("compute function : input param", sym, minutesOff); 
  const query = model.find({ symbol: sym, minutes_offs: minutesOff }).sort({ minutes_offs: +1 }); 
  return query.exec(); 
};

可选优化:并行执行版本

如果你的业务场景不需要严格按顺序处理每个minuteOff,可以用Promise.all并行发起所有请求,大幅提高效率:

const computeAggregate = async (model, sym) => { 
  try {
    const distMinutes = await model.collection.distinct("minutes_offs", { symbol: sym });
    
    // 并行处理所有异步任务
    await Promise.all(distMinutes.map(async (minuteOff) => {
      console.log("inside minutes off", minuteOff); 
      const records = await fetchRecords(model, sym, minuteOff); 
      const aggData = getAggregateData(records); 
      createCollection(aggData); 
    }));
  } catch (error) {
    console.log("error in computeAggregate", error);
  }
} 

这样所有fetchRecords请求会同时触发,适合对执行顺序没有要求的场景。

内容的提问来源于stack exchange,提问作者user2130951

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:14:57