为了账号安全,请及时绑定邮箱和手机立即绑定

用 promises 和 undefined var 理解奇怪的错误

用 promises 和 undefined var 理解奇怪的错误

蝴蝶刀刀 2022-10-08 15:04:46
我刚刚发现当几乎同时触发 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。很少有理由再使用varasletconst让您更好地控制变量的范围。

要在严格模式下运行您的模块,请插入:

'use strict';

在任何其他 Javascript 语句之前。

或者,使用 TypeScript 之类的东西,它不会让你做一些草率的事情,比如不声明你的变量。


查看完整回答
反对 回复 2022-10-08
  • 1 回答
  • 0 关注
  • 107 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号