如果使用var关键字node,则var未定义

时间:2018-08-01 22:31:54

标签: mysql node.js express

构建一个小型MVC。当我从模型收到结果时,如果我使用“ var”关键字,则用于发送到视图的变量是不确定的。如果我不使用关键字,那么对象就很好了。发生什么事了?

控制器

const homeModel = require('../models/homeModel.js');

exports.index = function(req, res){

homeModel.getAllStores(function (err, res) {
    if (err) return err;
    stores = res; // Works
    var stores = res // Undefined
})

console.log(stores);
res.render('home', {stores: stores});
}

这是模型

const db = require('../db.js');

exports.getAllStores = function(done) {

db.query('select * from stores;', (err, rows) => {
    if (err) return done(err);

    let resultJson = JSON.stringify(rows);
    resultJson = JSON.parse(resultJson);

    return done(null, resultJson);

})
}

1 个答案:

答案 0 :(得分:1)

您需要将stores的声明移到包含homeModel.getAllStores()的函数中。这是因为JavaScript是function (lexically) scoped,所以变量的作用域是最接近的封闭函数。您可以详细了解使用var声明的变量如何在MDN上工作。

在Node.js中,如果您没有在变量之前提供var关键字,那么它将在全局范围内运行它的模块,这就是console.log(stores)在您使用时起作用的原因stores = res,而不是var stores = res

要使用var正确定义变量的范围,只需将声明移至要导出的函数即可。

此外,您的console.log()res.render()调用是在执行homeModel.getAllStores()的回调函数并设置stores = res之前发生的。由于res.render()console.log()仅在对homeModel.getAllStores()的回调中可以按预期工作,因此您可以简化index()和对homeModel.getAllStores()的回调。

const homeModel = require('../models/homeModel.js')

exports.index = (req, res) => {
  return homeModel.getAllStores((err, stores) => {
    if (err) {
      throw err
    }

    console.log(stores)
    return res.render('home', {stores})
  })
}

您还可以使用util.promisify()async/await来写得更简单。

const {promisify} = require('util')
const getAllStores = promisify(require('../models/homeModel').getAllStores)

const index = async (req, res) => {
  let stores
  try {
    stores = await getAllStores()
  } catch (err) {
    console.error(err)
    return res.sendStatus(500)
  }

  return res.render('home', {stores})
}

module.exports = {index}

这里是一个示例,其中Promise.all()等待带有假设UserModelgetAllUsers()的{​​{1}}与homeModel.getAllStores()相同但查询{{1} }表。

users