Node.js+AWS Lambda:回调后继续执行,无需等待推送响应
解决AWS Lambda异步执行推送通知的时效优化问题
我明白你的需求——数据库操作完成后,不需要等待推送通知的结果就让Lambda函数返回,优先保证执行速度。你的问题核心在于调用推送Lambda时用了同步调用模式,导致当前函数必须等待推送完成才能结束。下面是具体的解决方案:
关键问题分析
你当前调用sendPushNotification Lambda时使用了InvocationType: 'RequestResponse',这是AWS Lambda的同步调用模式:当前函数会一直等待目标Lambda执行完成并返回结果后才继续,这就是为什么需要推送时函数变慢的原因。
解决方案步骤
1. 修改数据库插入函数的Lambda调用模式
把InvocationType改成Event,这是异步调用模式:当前Lambda会立即返回,不需要等待推送Lambda的执行结果,完全符合你“无需等待推送服务器回复”的需求。
同时要调整代码顺序:先发起异步推送调用,再执行callback返回结果(避免Lambda进程在推送调用前冻结)。
修改后的数据库插入函数代码:
const AWS = require('aws-sdk'); var mysql = require('mysql'); var lambda = new AWS.Lambda(); exports.handler = (event, context, callback) => { var connection = mysql.createConnection({ host: "databaseHost", user: "databaseUser", password: "databasePassword", database: "databaseName", multipleStatements: true }); var sql = "INSERT INTO someTable SET item_id = ?, item_name = ?" var inserts = [event.itemId, event.itemName]; connection.query(sql, inserts, function (error, results, fields) { connection.end(); if (error) { callback(error); return; } // 如果需要推送,发起异步Lambda调用 if (event.userToken !== null) { var pushPayload = { "deviceToken": event.deviceToken }; var pushParams = { FunctionName: 'sendPushNotification', InvocationType: 'Event', // 改成异步调用模式,无需等待结果 LogType: 'Tail', Payload: JSON.stringify(pushPayload) }; // 异步调用,不需要等待结果 lambda.invoke(pushParams, function (err) { // 即使推送调用发起失败,也不影响主流程返回 if (err) { console.error('推送调用发起失败:', err); } // 不管推送是否成功,都立即返回数据库操作结果 callback(null, results); }); } else { callback(null, results); } }); };
2. 优化推送通知函数的代码(可选但推荐)
原推送函数里有一些小问题和过时用法,比如context.succeed已经被弃用,还有变量名错误(deviceToken应该对应token),可以优化成更现代的写法:
const AWS = require('aws-sdk'); var ssm = new AWS.SSM({ apiVersion: '2014-11-06' }); var apn = require("apn"); exports.handler = async (event) => { // 使用async/await让代码更清晰 var options = { token: { key: "key", keyId: "keyId", teamId: "teamId" }, production: true }; const token = event.deviceToken; // 修正变量名错误 var apnProvider = new apn.Provider(options); var notification = new apn.Notification(); notification.alert = "message"; notification.topic = "com.example.Example"; try { await apnProvider.send(notification, [token]); console.log('推送发送成功'); } catch (err) { console.error('推送发送失败:', err); } finally { await apnProvider.shutdown(); // 关闭APN连接,避免资源泄漏 } return { statusCode: 200, body: '推送处理完成' }; };
额外说明
- 使用
InvocationType: 'Event'时,当前Lambda不会接收推送Lambda的执行结果,也不会处理它的错误,完全符合你“偶发推送失败无需在意”的需求。 - 异步调用时,AWS会负责把请求放入队列,推送Lambda会异步执行,不用担心请求丢失(除非出现极端服务故障)。
- 如果需要记录推送的执行情况,可以在推送Lambda里添加CloudWatch日志,后续通过日志查看推送结果。
内容的提问来源于stack exchange,提问作者alionthego
相关产品推荐
相关产品推荐

