【Azure 应用服务】Azure JS Function 异步方法中执行SQL查询后,Callback函数中日志无法输出问题

这篇具有很好参考价值的文章主要介绍了【Azure 应用服务】Azure JS Function 异步方法中执行SQL查询后,Callback函数中日志无法输出问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

问题描述

开发 Azure JS Function(NodeJS),使用 mssql 组件操作数据库。当SQL语句执行完成后,在Callback函数中执行日志输出 context.log(" ...") , 遇见如下错误:

Warning: Unexpected call to 'log' on the context object after function execution has completed.

Please check for asynchronous calls that are not awaited or calls to 'done' made before function execution completes. 

Function name: HttpTrigger1. Invocation Id: e8c69eb5-fcbc-451c-8ee6-c130ba86c0e9. Learn more: https://go.microsoft.com/fwlink/?linkid=2097909

错误截图

【Azure 应用服务】Azure JS Function 异步方法中执行SQL查询后,Callback函数中日志无法输出问题

 

问题解答

JS 函数代码(日志无法正常输出)

var sql = require('mssql');
var config = {
    user: 'username',
    password: 'Password',
    server: '<server name>.database.chinacloudapi.cn', // You can use 'localhost\\instance' to connect to named instance
    database: 'db name',

    options: {
        encrypt: true // Use this if you're on Windows Azure
    }
}
module.exports
= async function (context, req) { context.log('JavaScript HTTP trigger function processed a request.'); await callDBtoOutput(context); context.log('################'); //Default Code ... const name = (req.query.name || (req.body && req.body.name)); const responseMessage = name ? "Hello, " + name + ". This HTTP triggered function executed successfully." : "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."; context.res = { // status: 200, /* Defaults to 200 */ body: responseMessage }; } async function callDBtoOutput(context) { try { context.log("Some Message from callDBtoOutput") var ps = new sql.PreparedStatement(await sql.connect(config)) await ps.prepare('SELECT SUSER_SNAME() ', async function (err) { if (err) { context.log(err) } context.log("start to exec sql ...from callDBtoOutput") await ps.execute({}, async function (err, recordset) { // ... error checks context.log(recordset) context.log("Login SQL DB successfully....from callDBtoOutput") ps.unprepare(function (err) { // ... error checks }); }); }); } catch (error) { context.log(`Some Error Log: from callDBtoOutput`, error); } }

在 callDBtoOutput() 函数中,调用sql prepare 和 execute方法执行sql语句,虽然已经使用了async和await关键字,但根据测试结果表明:Function的主线程并不会等待callback函数执行。当主线程中context对象释放后,子线程中继续执行context.log函数时就会遇见以上警告信息。 

 

为了解决以上prepare和execute方法中日志输出问题,需要使用其他执行sql的方法。在查看mssql的官方说明(https://www.npmjs.com/package/mssql#query-command-callback)后,发现query方法能够满足要求。

query (command, [callback])

Execute the SQL command. To execute commands like create procedure or if you plan to work with local temporary tables, use batch instead.

Arguments

  • command - T-SQL command to be executed.
  • callback(err, recordset) - A callback which is called after execution has completed, or an error has occurred. Optional. If omitted, returns Promise.

 

经过多次测试,以下代码能完整输出Function过程中产生的日志。

JS 函数执行SQL代码(日志正常输出)

var sql = require('mssql');

var config = {
    user: 'username',
    password: 'Password',
    server: '<server name>.database.chinacloudapi.cn', // You can use 'localhost\\instance' to connect to named instance
    database: 'db name',

    options: {
        encrypt: true // Use this if you're on Windows Azure
    }
}

module.exports = async function (context, req) {
    context.log('JavaScript HTTP trigger function processed a request.');
    
    // context.log('call callDBtoOutput 1');
    // await callDBtoOutput(context);

    //context.log('call callDBtoOutput 2');
    await callDBtoOutput2(context);

    context.log('################');
    const name = (req.query.name || (req.body && req.body.name));
    const responseMessage = name
        ? "Hello, " + name + ". This HTTP triggered function executed successfully."
        : "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response.";

    context.res = {
        // status: 200, /* Defaults to 200 */
        body: responseMessage
    };
}

async function callDBtoOutput2(context) {
    context.log("1: Call SQL Exec function ....")
    await sql.connect(config).then(async function () {
        // Query
        context.log("2: start to exec sql ... ")     
        await new sql.Request().query('SELECT SUSER_SNAME() ').then(async function (recordset) {
            context.log("3: Login SQL DB successfully.... show the Query result") 
            context.log(recordset);

        }).catch(function (err) {
            // ... error checks
        });
    })
    context.log("4: exec sql completed ... ") 
}

结果展示(完整日志输出)

【Azure 应用服务】Azure JS Function 异步方法中执行SQL查询后,Callback函数中日志无法输出问题

 

参考资料

node-mssql: https://www.npmjs.com/package/mssql

context.done : https://learn.microsoft.com/en-us/azure/azure-functions/functions-reference-node?pivots=nodejs-model-v3&tabs=javascript%2Cwindows-setting-the-node-version#contextdone

The context.done method is deprecated

Now, it's recommended to remove the call to context.done() and mark your function as async so that it returns a promise (even if you don't await anything).文章来源地址https://www.toymoban.com/news/detail-435158.html

到了这里,关于【Azure 应用服务】Azure JS Function 异步方法中执行SQL查询后,Callback函数中日志无法输出问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • linux系统(centos、ubuntu、银河麒麟服务、uos、deepin)判断程序是否已安装,通用判断方法:使用所有应用和命令的判断

    项目中需要判断linux服务器中是否已经安装了某个服务 方法有很多种,但是很多都不通用, 脚本代码就不容易做成统一的 用下面的脚本代码去进行判断 脚本意思如下: 输入java -version命令,将返回的字符串输出第一行 如果里面包含java version这个字符串则说明jdk已经安装  下

    2024年02月11日
    浏览(42)
  • JS执行机制--同步与异步

    单线程 JavaScript语言具有单线程的特点,同一个时间只能做一件事情。这是因为JavaScript脚本语言是为了处理页面中用户的交互,以及操作DOM而诞生的。如果对某个DOM元素进行添加和删除,不同同时进行。应该是先添加,再删除,事件有序。 单线程的特点是所有任务都需要排队

    2023年04月20日
    浏览(23)
  • js中如何顺序执行异步任务

    在js中,任务可分为两种,同步任务和异步任务。 (1) 同步任务 又叫 非耗时任务 ,指的是在主线程排队执行的那些任务 只有前一个任务执行完毕,才能执行后一个任务 (2) 异步任务 又叫 耗时任务 ,异步任务由JavaScript委托给宿主环境进行执行 当异步任务执行完成后,会通知

    2024年02月09日
    浏览(30)
  • Microsoft Defender SmartScreen 阻止了无法识别的应用启动,Windows已阻止此软件和无法验证发布者两个问题的解决方法(以腾讯云服务器为例的三种保姆级图文解决方法)

    提示:转到日常小技巧专栏,观看更多内容! 点我直达–日常小技巧专栏 在使用腾讯云服务器2019server的时候(这个安全提示好像是win7和win10的特色),运行一些网上下载的软件的时候有安全提示: 强行进行本次运行(本次可以运行,但是之后可能还是会有弹窗) 信任单个

    2024年02月03日
    浏览(72)
  • Tomcat 应用服务 WEB服务

    简述: 目前来说IBM的 WebSphere ,Oracle的 Weblogic 占据了市场上Java语言Web站点的部分份额,该两种软件由于无与伦比的性能及可靠性等优势被广泛应用于大型互联网公司的Web场景中,但是其高昂的价格也使得中小型互联网公司对此望而却步。 Tomcat自5.x版本以来,其性能上已经得

    2024年02月13日
    浏览(28)
  • 【tomcat】应用服务

    准备环境 三台虚拟机 192.168.1.120 192.168.1.122 192.168.1.131 三台虚拟机关闭防火墙 、查看光盘 、检测yun创库 查看JDK是否安装 [root@localhost ~]# java -version openjdk version \\\"1.8.0_161\\\" //这是系统自带的rpm方式安装 OpenJDK Runtime Environment (build 1.8.0_161-b14) OpenJDK 64-Bit Server VM (build 25.161-b14, mixed

    2024年02月12日
    浏览(29)
  • 服务网关Gateway_微服务中的应用

    没有服务网关 问题: 地址太多 安全性 管理问题 为什么要使用服务网关 网关是微服务架构中不可或缺的部分。使用网关后,客户端和微服务之间的网络结构如下。 注意: 网关统一向外部系统(如访问者、服务)提供REST API。在SpringCloud 中,使用Zuul、Spring Cloud Gateway等作为

    2024年02月07日
    浏览(36)
  • SpringBoot异步执行方法

    1. 源码跟踪 1.简单描述 在SpringBoot2.0.9之前需要手动自定义线程池(如下2.1), 然后指定线程池的名称 SpringBoot2.0.9以及之前的版本,使用的线程池默认是 SimpleAsyncTaskExcutor , , 之后的版本使用的是 ThreadpoolTaskExecutor 并且不需要手动的创建当前线程池(但往往我们还是会手动指定,具体原

    2024年02月07日
    浏览(26)
  • 分布式应用服务的拆分

    将需求转化为分布式应用服务的过程可以按照以下步骤进行: 理解需求:首先,你需要仔细阅读和理解业务需求。与相关的利益相关者(如业务分析师、产品经理等)进行沟通,确保你对需求的理解是准确的。 设计架构:根据需求,设计一个适合的分布式应用架构。这包括

    2024年02月05日
    浏览(45)
  • 服务发现:在区块链中的应用:如何通过服务发现来提高区块链应用效率和客户满意度

    作者:禅与计算机程序设计艺术 随着数字货币、区块链技术的普及,以及互联网公司对其功能的整合,传统的单体应用模式已不能适应这一趋势,需要逐渐向分布式架构转型。分布式架构通常使用微服务架构的方式,将一个系统分解成多个小模块,各自独立运行且互相通信。

    2024年02月11日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包