我刚刚发现当几乎同时触发 2 个请求时,我的 API 正在做一些奇怪的事情。我发现问题是我在下面的“用户”变量之前缺少“var”声明,但我真的很好奇导致下面描述的错误的根本问题:我有两个 API 端点调用相同的函数,如下所示:router.get('/refresh_session_token', function (req, res) { let user_id = req.body.user_id // The value sent is 8 findUserWithId(user_id) .then(user_data => { user = user_data // I forgot 'var' here }) .then(() => { console.log(user) // This should always show user data from user_id = 8 })}router.get('/resend_invite', function (req, res) { let user_id = req.body.user_id // The value sent is 18 findUserWithId(user_id) .then(user_data => { user = user_data // I forgot 'var' here }) .then(() => { console.log(user) // This should always show user data from user_id = 18 })}const findUserWithId = (id) => { return knex.raw(`SELECT * FROM users WHERE id = ?`, [id]).then((data) => data.rows[0])}所有这些代码都在我通过 module.exports = router; 导出的同一个文件中我发现,如果我几乎同时触发端点/refresh_session_token和/resend_invite,每个端点都有两个不同的 user_id,有时我的 console.log 会返回相同的结果,就好像我使用相同的 user_id 一样。向用户添加 var 解决了这个问题,但我对后台实际发生的事情感到非常惊讶。你有什么主意吗?
1 回答

守候你守候我
TA贡献1802条经验 获得超10个赞
当你没有声明你的变量并且你没有在 Javascriptstrict
模式下运行你的模块时,那么首先分配给该变量:
user = user_data
创建一个名为 的自动全局变量user
。这意味着您的两条路线将共享同一个变量。
而且,由于您的两条路由都具有异步操作,即使是单线程的东西,您的两条路由仍然可以同时进行,并且都尝试使用相同的全局变量。一条路线将覆盖另一条路线的值。这在基于服务器的代码中是一场灾难,因为通常,在您投入生产之前,该错误不会出现,而且很难找到可重现的案例。
最好的答案是始终在严格模式下运行代码,然后 JS 解释器会将其设为错误,并且您将永远不会被允许以这种方式运行代码。错误将很快被发现。
let
那么显然,总是用or声明变量const
。很少有理由再使用var
aslet
并const
让您更好地控制变量的范围。
要在严格模式下运行您的模块,请插入:
'use strict';
在任何其他 Javascript 语句之前。
或者,使用 TypeScript 之类的东西,它不会让你做一些草率的事情,比如不声明你的变量。
添加回答
举报
0/150
提交
取消