Lambda中的NodeJS异步未运行所有条目

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Lambda中的NodeJS异步未运行所有条目相关的知识,希望对你有一定的参考价值。

我有一个NodeJs10 Lambda函数,可以解析数据库中的条目并将其保存回数据库。当我在本地运行时,它将解析所有条目。当我在Lambda函数中运行它时,它仅解析3-4个条目。我最好的猜测是Lambda以不同的方式处理异步调用,并认为所有条目都已解析。

如何使我的Lambda函数在关闭之前运行所有条目?

我的代码全局看起来像这样:

'use strict';

// Packages
var Mercury = require('@postlight/mercury-parser');
var mysql = require('mysql');

// All necessery sql Queries
var sqlSelect = "Select some stuff";
var sqlUpdateText = "Update some stuff";

exports.handler = async function(event, context) 
    // Define the database used in pools
    var pool = Mysql.createPool(
    );

    // Promise where the links and id's are fetched from the database
    let fetchLink = new Promise((resolve, reject) => 
        pool.getConnection((err, connection) =>    // Connection with the database
        );
    );

    // After getting the links and id's, parse the text from the links and put them in a JSON object
    return fetchLink.then(async function (dbresult) 
        if (dbresult.length > 0) 
            await parser();
        
        return textObj;
    )
    // After parsing
        .then(function (textObj) 
            if (Object.getOwnPropertyNames(textObj).length !== 0) 
                pool.getConnection((err, connection) => 
                    if (err) throw err;
                    for (let id in textObj) 
                        // Do some db stuff
                    
                    connection.release();
                    pool.end();
                );
             else 
                pool.end();
            
        )
        // Catch the error message's
        .catch(function (err) 
            console.log(err);
            pool.end();
        );
;
答案

处理程序功能在您不在任何地方使用await时不需要是异步的。如果您返回诺言,无论如何它都是异步的。我不确定fetchLink Promally的外观,但是在这里它无法解决/拒绝任何事情,因此功能可能会在超时时完成。小计,您需要像这样修复它

    let fetchLink = new Promise((resolve, reject) => 
        pool.getConnection((err, connection) =>    // Connection with the database
            if(err) reject(err);
            resolve(connection);
        );
    );

同样,如果要确保处理程序函数以释放连接并结束池为结束,在解析和捕获错误之后,也更好地返回promise。

    .then(function (textObj) 
        return new Promise((resolve, reject) => 
            if (Object.getOwnPropertyNames(textObj).length !== 0) 
                pool.getConnection((err, connection) => 
                    if (err) return reject(err);
                    for (let id in textObj) 
                        // Do some db stuff
                    
                    connection.release();
                    pool.end();
                    resolve();
                );
             else 
                pool.end();
                resolve();
            
            
    )

如果connection.release()pool.end()函数是promise或具有回调,则也应将它们绑定在Promise中,然后等待。

另一答案

Lambda不会等待您的fetchLink.then()完成。根据您的情况,在await之前添加fetchLink.then()将完成此工作。

// After getting the links and id's, parse the text from the links and put them in a JSON object
    return await fetchLink.then(async function (dbresult) 
        if (dbresult.length > 0) 
            await parser();
        
        return textObj;
    )

如果以上解决方案仍不能解决您的问题。检查调用异步api的回调是否已正确处理。

// After parsing
        .then(function (textObj) 
            if (Object.getOwnPropertyNames(textObj).length !== 0) 
                // HANDLE THIS ASYNC OR IT WILL NOT BE WAITED BY LAMBDA
                pool.getConnection((err, connection) => 
                    if (err) throw err;
                    for (let id in textObj) 
                        // Do some db stuff
                    
                    connection.release();
                    pool.end();
                );
             else 
                pool.end();
            
        )

文档:https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html

以上是关于Lambda中的NodeJS异步未运行所有条目的主要内容,如果未能解决你的问题,请参考以下文章

使用 lambda 扫描/查询 dynamodb 表中的特定条目

解密aws kms密钥时出现Nodejs异步问题

Nodejs API调用将未定义返回给lambda函数

serverless.yml 中的运行时变量未设置节点版本

从lambda层加载时无服务器脱机未定义模块

Task.Run 中的异步 lambda 与常规 lambda [重复]