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

Javascript Node.js Express服务器-全局变量问题,javascript,node.js,express,server,backend,Javascript,Node.js,Express,Server,Backend,为了避免这个问题:我并没有在这个问题上发布bug 问题 我最近发现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

为了避免这个问题:我并没有在这个问题上发布bug


问题
我最近发现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
    })
}
我发现的问题是,在执行异步函数时,诸如
payload
id1
等全局变量被覆盖。(如果下一个请求是在第一个请求完成之前发出的)因此,一些函数在执行时输入错误,出现了奇怪的响应


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

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函数占用的时间,处理程序将使用错误的数据
  • 取决于全局变量的用法。如果您有一些对所有请求都有效但可能根据其他条件而改变的内容,那么在我看来,使用全局变量是完全有意义的。但是对于您的用例来说,这绝对是错误的方法,正如您已经发现的那样
  • 不可以。唯一的选择是传递一个具有多个属性的对象,而不是多个参数——但基本上是一样的
  • 是的,因为变量是全局的,请求是异步的,所以每次都会覆盖变量。根据fetchData函数占用的时间,处理程序将使用错误的数据
  • (1) 在快车路线中使用“全局变量”是否愚蠢

    总体而言,全局变量确实被认为是不好的做法

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

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

    (3) 我的假设正确吗?当一个新请求调用这个特定路由时,这些“全局变量”会被覆盖吗

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

    (1) 在快车路线中使用“全局变量”是否愚蠢

    总体而言,全局变量确实被认为是不好的做法

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

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

    (3) 我的假设正确吗?当一个新请求调用这个特定路由时,这些“全局变量”会被覆盖吗


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

    感谢您的回复!一个小问题:如果在函数中声明这些变量,那么当同时有多个请求时,即使函数是
    async
    ?即使同时有多个请求,也没有问题,就像上面的解决方案中构造的那样,这应该不会有任何问题,因为所有函数只从它们自己的作用域访问变量。感谢您的回复!一个小问题:如果在函数中声明这些变量,那么当同时有多个请求时,即使函数是
    async
    ?即使同时有多个请求,也没有问题,就像上面的解决方案中构造的那样,这不应该有任何问题,因为所有函数只从它们自己的作用域访问变量。