使用Lambda Node.js更新DynamoDB列表元素遇错求助
解决Lambda更新DynamoDB列表时的"Winter is not a function"错误
你遇到的这个错误核心原因是**Array.findIndex()的用法不正确**,另外你的DynamoDB更新表达式也存在语法问题,我来一步步帮你修正:
1. 修复findIndex的调用错误
findIndex()方法需要传入一个回调函数,用来判断数组元素是否匹配,但你直接传入了字符串option,JavaScript会尝试把这个字符串当作函数执行,自然就抛出了"Winter is not a function"的错误。
正确的写法应该是传入一个箭头函数,对比数组中的每个元素和目标选项:
const index = options.findIndex(opt => opt === option);
因为你用的是DocumentClient,它会自动把DynamoDB的L(列表)类型转换成普通JavaScript数组,S类型转换成字符串,所以直接用===比较即可。
2. 修正DynamoDB的UpdateExpression语法
DynamoDB的更新表达式中,列表的索引不能直接用变量占位,需要通过ExpressionAttributeNames来动态指定索引位置,否则会触发语法错误。
你的更新参数需要调整成这样:
const updateParams = { TableName: 'QnV', Key: { 'qid': qid }, UpdateExpression: 'set #votes[#idx] = :vote', ExpressionAttributeNames: { '#votes': 'votes', '#idx': index.toString() // 索引需要转成字符串作为属性名占位符 }, ExpressionAttributeValues: { ':vote': vote }, ReturnValues: 'UPDATED_NEW' };
这里用#idx来动态替换列表的索引位置,同时把索引转成字符串(因为ExpressionAttributeNames的键必须是字符串)。
3. 完整修正后的Lambda代码
const AWS = require('aws-sdk'); const docClient = new AWS.DynamoDB.DocumentClient(); exports.handler = async (event, context) => { const qid = event.qid; const option = event.option; const vote = event.vote; const params = { TableName : 'QnV', Key: { qid: qid } } try { const data = await docClient.get(params).promise(); // 增加空值判断,避免Item不存在时出错 if (!data.Item) { return { statusCode: 404, body: JSON.stringify({ message: 'Question not found' }) }; } const options = data.Item.options; const index = options.findIndex(opt => opt === option); // 检查选项是否存在 if (index === -1) { return { statusCode: 400, body: JSON.stringify({ message: 'Invalid option' }) }; } const updateParams = { TableName: 'QnV', Key: { 'qid': qid }, UpdateExpression: 'set #votes[#idx] = :vote', ExpressionAttributeNames: { '#votes': 'votes', '#idx': index.toString() }, ExpressionAttributeValues: { ':vote': vote }, ReturnValues: 'UPDATED_NEW' }; const updateData = await docClient.update(updateParams).promise(); return { statusCode: 200, body: JSON.stringify(updateData) }; } catch (err) { // 返回更详细的错误信息方便调试 return { statusCode: 500, body: JSON.stringify({ message: err.message, stack: err.stack }) }; } };
额外优化点
- 增加了
data.Item的空值判断:避免当指定qid不存在时,访问data.Item.options抛出错误 - 增加了选项存在性检查:如果传入的
option不在列表中,返回400错误而不是继续执行更新 - 优化了错误返回:包含错误栈信息,更便于调试
现在用你的测试事件重新测试,应该就能正常更新DynamoDB中对应选项的投票数了。
内容的提问来源于stack exchange,提问作者aye
相关产品推荐
相关产品推荐

