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
相关产品推荐
相关产品推荐

