【问题标题】:Node.js Express Server - Global Variable IssueNode.js Express 服务器 - 全局变量问题
【发布时间】:2019-03-15 12:33:38
【问题描述】:

为了解决这个问题:我并不是真的在这个问题中发布错误!


问题
我最近发现我的 Node.js 和 Express 后端代码存在问题,同时从前端发出多个请求。假设我的一个端点如下所示:

var payload, id1, id2, data1, data2

exports.someFunction = async (req, res) => {
    payload = req.body.payload
    id1 = req.params.id1
    id2 = req.query.id2
    try {
        data1 = await fetchData1()
        data2 = await fetchData2()
        return responseHandler.success({ data1, data2 })
    } catch (err) {
        return responseHandler.error(err)
    }
}

async function fetchData1() {
    return new Promise((resolve, reject) => {
        // fetch data from database by accessing
        // payload, id1, id2
        // here
    })
}

我发现的问题是,在执行异步函数时,payloadid1 等全局变量被覆盖了。 (如果下一个请求是在第一个请求完成之前发出的)因此执行了一些输入错误的函数并出现了奇怪的响应。


解决方案
然后我的解决方案是将这些全局变量移到函数内部,这导致函数参数的大量使用:

exports.someFunction = async (req, res) => {
    const payload = req.body.payload
    const id1 = req.params.id1
    const id2 = req.query.id2
    try {
        const data1 = await fetchData1(payload, id1, id2)
        const data2 = await fetchData2(payload, id1, id2, data1)
        return responseHandler.success({ data1, data2 })
    } catch (err) {
        return responseHandler.error(err)
    }
}

async function fetchData1(payload, id1, id2) {
    return new Promise((resolve, reject) => {
        // fetch data from database
    })
}

如您所见,代码变得非常混乱,这实际上是我首先使用全局变量的原因。


我的实际问题

  • (1) 在 express 路由中使用“全局变量”是不是很傻?
  • (2) 是否有更好的方法为其他函数提供数据,而不是每次都输入所有参数
  • (3) 我的假设是否正确,即当新请求调用此特定路由时,那些“全局变量”会被覆盖?

【问题讨论】:

    标签: javascript node.js express server backend


    【解决方案1】:

    (1) express 路由中使用“全局变量”是不是很傻?

    全局变量确实被普遍认为是不好的做法。

    (2) 有没有更好的方法为其他函数提供数据,而不是每次都输入所有参数

    每次都输入它们有什么问题?您显示的代码对我来说似乎非常好。对于可读性和测试来说,明确地显示函数的依赖关系通常会更好。

    (3) 我的假设是否正确,即当新请求调用此特定路由时,那些“全局变量”会被覆盖?

    是的,javascript 默认同步执行,直到出现async/await 块。在您的示例中,不能保证 async 块将在发出另一个请求之前得到解决,这使得该代码非常脆弱。

    【讨论】:

    • 感谢您的回复!一个小问题:如果在函数中声明这些变量,那么在同时有多个请求时没有问题,即使函数是async?
    • 即使有许多同时请求,如您在上面的解决方案中所构造的那样,也不应该有任何问题,因为所有函数都只能访问它们自己范围内的变量。
    【解决方案2】:
    1. 取决于全局变量的使用。如果您有一些对所有请求都有效但可能会根据其他条件发生变化的东西,那么在我看来,使用全局变量是完全有意义的。但是对于您的用例,这绝对是您已经发现的错误方法。
    2. 没有。唯一的选择是传递一个具有多个属性而不是多个参数的对象 - 但基本上是一样的。
    3. 是的,因为变量是全局的并且请求是异步的,所以每次都会覆盖变量。根据您的 fetchData 函数花费的时间,您的处理程序将使用错误的数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-11
      • 2015-07-01
      • 1970-01-01
      • 2011-07-23
      相关资源
      最近更新 更多