【问题标题】:Will Node.js continue executing statements after callback?Node.js 会在回调后继续执行语句吗?
【发布时间】:2018-09-10 21:21:28
【问题描述】:

我在 lambda 函数中使用 node.js 将数据保存到 mysql 数据库,然后发送推送通知。我希望在保存到数据库之后和发送推送通知之前进行回调以提高性能。但我希望推送代码在回调后继续执行。

这就是我所拥有的:

const AWS = require('aws-sdk');
var mysql = require('mysql');
var apn = require("apn");

exports.handler = (event, context, callback) => {

    var connection = mysql.createConnection({
        host: "databaseHost",
        user: "databaseUser",
        password: "databasePassword",
        database: "databaseName",
    });

    var sql = "INSERT INTO some_table SET some_id = ?";
    var inserts = [event.someId];

    connection.query(sql, inserts, function (error, results, fields) {
        connection.end();
        if (error) {
            callback(error);
        } else {
            var options = {
                token: {
                    key: "key.p8",
                    keyId: "keyId",
                    teamId: "teamId"
                },
                production: true
            };
            var message = "Some Message";
            var apnProvider = new apn.Provider(options);

            var deviceTokens = event.deviceTokenArray;

            var notification = new apn.Notification();
            notification.alert = message;

            notification.topic = "com.example.example";

            apnProvider.send(notification, deviceTokens).then((response) => {
                callback(null, event.arguments.input);
            });
        }
    });
};

我希望apnProvider 函数中的回调在该函数之前发生,但该函数继续执行。理想情况下,我希望将推送消息放在单独的文件中,但我想这是一个不同的问题,我稍后会解决。

【问题讨论】:

    标签: node.js asynchronous callback


    【解决方案1】:

    可能是也可能不是好的做法,但它是完全可行的。只需回调并让其余代码执行。

    const AWS = require('aws-sdk');
    var mysql = require('mysql');
    var apn = require("apn");
    
    exports.handler = (event, context, callback) => {
    
        var connection = mysql.createConnection({ /* .. */ });
    
        var sql = "INSERT INTO some_table SET some_id = ?";
        var inserts = [event.someId];
    
        connection.query(sql, inserts, function (error, results, fields) {
            connection.end();
            if (error) {
                callback(error);
            } else {
                callback(null, event.arguments.input);
    
                // consider moving this out to a separate lambda, the
                // function is essentially done
                var options = { /*  */ };
                var message = "Some Message";
                var apnProvider = new apn.Provider(options);
    
                var deviceTokens = event.deviceTokenArray;
    
                var notification = new apn.Notification();
                notification.alert = message;
    
                notification.topic = "com.example.example";
    
                apnProvider.send(notification, deviceTokens).then((response) => {
                  console.log('log response here');
                });
            }
        });
    };
    

    理想情况下,您很可能希望拆分您的 lambda,这样它们就不会做太多事情。也许有一个 lambda 只是查询数据库,另一个发出通知,另一个持久化一些数据等。

    【讨论】:

    • 如果我要将 lambda 拆分为两个单独的函数,一个用于查询数据库,另一个用于发送推送,那么我是否需要在数据库函数返回后从客户端调用推送 lambda 函数?或者我可以在第一个数据库查询函数中这样做吗?
    • 你绝对可以从数据库查询函数中调用它。这只是一个功能。无论如何,出于测试目的等,将其提取到单独的函数中可能是个好主意。您可能还想在其他地方调用推送通知逻辑。
    猜你喜欢
    • 2011-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-14
    • 1970-01-01
    • 1970-01-01
    • 2021-02-26
    • 1970-01-01
    相关资源
    最近更新 更多