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

Lambda中使用forEach调用异步DynamoDB query函数报错求助

问题解决:DynamoDB扫描后异步查询的语法错误

错误根源

你遇到的unexpected token queryItems错误,核心原因是在非async函数里使用了await:arr.forEach的回调是普通函数,里面调用await queryItems(Item)违反了语法规则——await只能出现在async标记的函数内部。

另外原代码还有一个隐藏问题:docClient.scan用了回调模式,而外层handler是async函数,这会导致Lambda可能在扫描和查询操作完成前就提前结束,因为回调的执行不会阻塞async函数的流程。

修正后的代码

下面是修复后的完整代码,同时优化了异步流程的处理:

'use strict';

const aws = require('aws-sdk');
const docClient = new aws.DynamoDB.DocumentClient();

const paramsAll = {
  TableName: 'MyTable',
  Select: "ALL_ATTRIBUTES"
};

exports.handler = async (event, context) => {
  try {
    // 改用promise版scan,用await阻塞等待扫描结果
    const scanData = await docClient.scan(paramsAll).promise();
    const items = scanData.Items;
    
    // 提取所有seq到数组
    const seqArr = items.map(item => item.payload.seq);
    
    // 方式1:并行执行所有查询(效率更高,适合查询数量不多的场景)
    const allQueryResults = await Promise.all(seqArr.map(seq => queryItems(seq)));
    // 遍历处理每个查询结果
    allQueryResults.forEach((result, index) => {
      const currentSeq = seqArr[index];
      // 这里写处理逻辑,比如:
      console.log(`seq ${currentSeq} 的查询结果:`, result);
    });

    // 方式2:串行执行查询(适合查询数量多,避免触发DynamoDB并发限制)
    // for (const seq of seqArr) {
    //   const result = await queryItems(seq);
    //   // 处理当前seq的查询结果
    //   console.log(`seq ${seq} 的查询结果:`, result);
    // }

    return { success: true, message: '操作完成' };
  } catch (err) {
    console.error('操作失败:', err);
    return { error: err.message };
  }
};

async function queryItems(p) {
  try {
    const params = {
      TableName: 'MyTable',
      KeyConditionExpression: '#seq = :value',
      ExpressionAttributeValues: { ':value': p },
      ExpressionAttributeNames: { '#seq': 'seq' }
    };
    const data = await docClient.query(params).promise();
    return data;
  } catch (err) {
    console.error(`查询seq ${p} 失败:`, err);
    throw err; // 抛出错误让上层catch处理,避免吞掉异常
  }
}

关键修改点

  • 将docClient.scan的回调模式改为promise()+await,确保异步流程的顺序执行,同时符合async函数的写法规范。
  • 用map替代forEach提取seq数组,代码更简洁。
  • 处理批量异步查询时,提供两种方案:
    • 并行查询:用Promise.all+map,一次性发起所有查询,效率更高,但要注意DynamoDB的并发请求限制(默认每秒最多1000次读写)。
    • 串行查询:用for...of循环逐个执行查询,避免并发过高触发限流,适合数据量较大的场景。
  • 修复了await只能在async函数内使用的问题:for...of的循环体在async的handler函数内,Promise.all的回调也不需要额外的await嵌套。
  • 优化了错误处理:在queryItems中抛出异常,让上层统一捕获,避免异常被隐藏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 07:05:22