Node.js Express 服务器 - 全局变量问题

Node.js Express Server - Global Variable Issue

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


问题
我最近发现我的 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. 取决于全局变量的使用。如果你有一些对所有请求都有效但可能会根据其他条件而改变的东西,那么在我看来使用全局变量是完全有意义的。但是对于您的用例,正如您已经发现的那样,这绝对是错误的方法。
  2. 没有。唯一的选择是传递一个具有多个属性而不是多个参数的对象——但基本上是一样的。
  3. 是的,因为变量是全局的并且请求是异步的,所以变量每次都会被覆盖。根据您的 fetchData 函数花费的时间,您的处理程序将使用错误的数据。

(1) Is it silly to use "global variables" in express routes?

全局变量通常被认为是不好的做法。

(2) Is there a better way of supplying other functions with data, rather than inputting all arguments every single time

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

(3) Is my hypothesis correct, that those "global variables" are overwritten when a new request calls this specific route?

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