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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:59:32