Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么异步函数不能在控制器内工作';s get()处理程序?_Javascript_Node.js_Express_Node Mssql - Fatal编程技术网

Javascript 为什么异步函数不能在控制器内工作';s get()处理程序?

Javascript 为什么异步函数不能在控制器内工作';s get()处理程序?,javascript,node.js,express,node-mssql,Javascript,Node.js,Express,Node Mssql,我正在使用Node和Express连接到SQL Server数据库。我在我的app.js文件中这样做,该文件设置了一个global变量来创建一个到数据库的connectionPool(为了简洁起见,我省略了一些样板文件): 我有一个名为offer.js的模型文件,它就是这样做的: async function getOffersAll() { await MSSQL_MYDB.connect(); // connects to the database try {

我正在使用Node和Express连接到SQL Server数据库。我在我的
app.js
文件中这样做,该文件设置了一个
global
变量来创建一个到数据库的
connectionPool
(为了简洁起见,我省略了一些样板文件):

我有一个名为
offer.js
的模型文件,它就是这样做的:

async function getOffersAll() {
    await MSSQL_MYDB.connect(); // connects to the database
    try {
        var result = await MSSQL_MYDB.request(MSSQL_MYDB).query('SELECT Top(1) * FROM [dbo].[Offer]');
        return result; // returns the recordset of data
    } catch (error) {
        console.log(error);
    } finally {
        if (MSSQL_MYDB){
            try {
            await MSSQL_MYDB.close(); // closes the DB connection
            }
            catch (error) {
                console.log('Error closing connection');
            }
        }

    }

}

exports.getOffersAll = getOffersAll;
到目前为止还不错。然后我有一个控制器文件
index.js
,它实际上不起作用(用注释解释):

我的问题是,为什么等待来自
Offer.getOffersAll()
的结果的第一个
async函数()
没有失败,但是放置在
router.get('/')
处理程序中的同一个异步函数失败并出现登录错误?如果我删除
var rsOffersAll=wait Offer.getOffersAll()router.get(“/”)
处理程序中执行code>,然后页面呈现,但我当然没有数据要传递给它

即使我将测试函数的值存储在变量中并尝试将其放入
router.get()
处理程序中,也会发生完全相同的情况,如下所示:

async function getOffersTest() {
          return await Offer.getOffersAll();
        }

router.get('/',  async function(req, res) {
         var rsOffersAll = await getOffersTest(); // still breaks
          console.dir(rsOffersAll);
          res.render('index', { pagetitle: 'Homepage'}); // still never renders
        });

我的最终问题是,如何解决这个问题,使它能够正常工作,即当访问主页时,路由器等待数据从数据库返回,然后我可以将其传递到我的视图,或者只要打印到控制台就可以了?

因为这一行
global.MSSQL\u MYDB=new MSSQL.ConnectionPool(DB\u MYDB\u Config),

当您在路由器之外执行此代码时

(async function () {
     var rsOffersAll = await Offer.getOffersAll();
     console.dir(rsOffersAll); // works great! recordset rsOffersAll is printed to console
  })();
getOffersAll可以访问全局变量, 并且您可以在线路
中成功连接数据库,等待MSSQL_MYDB.connect()//

但对于路由器,全局作用域是当前的module.exports对象,而不是全局对象

解决方案

您可以像这样在应用程序中设置
MSSQL\u MYDB

app.set('MSSQL\u MYDB')

然后你可以在下面的函数中得到同样的变量

router.get('/',  async function(req, res) {
     const MSSQL_MYDB = req.app.get('MSSQL_MYDB')
     var rsOffersAll = await getOffersTest(MSSQL_MYDB ); 
      console.dir(rsOffersAll);
      res.render('index', { pagetitle: 'Homepage'}); // still never renders
    });

整个问题刚刚解决,它是节点mssql包中的一个bug或其他东西。仅当您提供用户名和密码时,它才起作用。如果使用
选项:{trustedConnection:true}
启用windows身份验证,则路由器永远无法登录。我不知道为什么会出现这种情况,但如果您只提供用户名和密码(我使用sa进行测试),那么它工作正常。

调用
是否可能等待MSSQL_MYDB.connect()
导致错误,因为它已经连接?@TKoL我从未调用控制器中的两个
Offer.getOffersAll()
函数。我只叫它一次。。。因此,当我在我的
路由器.get('/')
部分中尝试它时,我将注释掉测试函数。因此,不应该有两个
等待MSSQL_MYDB_connect()正在运行。我试图移动它:
const DB_MYDB_Config={server:“localhost”,database:“MYDB”,选项:{trustedConnection:true};const MSSQL_MYDB=new MSSQL.ConnectionPool(DB_MYDB_Config)
进入我的
offer.js文件,它仍然不起作用。它不再在全局范围内,因此应该可以正常工作?您是否将其移动到
getOffersAll
函数内部?是-我在
getOffersAll
函数内部和外部都尝试了它。获取与登录失败相同的错误。
(async function () {
     var rsOffersAll = await Offer.getOffersAll();
     console.dir(rsOffersAll); // works great! recordset rsOffersAll is printed to console
  })();
router.get('/',  async function(req, res) {
     const MSSQL_MYDB = req.app.get('MSSQL_MYDB')
     var rsOffersAll = await getOffersTest(MSSQL_MYDB ); 
      console.dir(rsOffersAll);
      res.render('index', { pagetitle: 'Homepage'}); // still never renders
    });