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

我刚刚发现当几乎同时触发 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 解决了这个问题,但我对后台实际发生的事情感到非常惊讶。


你有什么主意吗?


蝴蝶刀刀
浏览 108回答 1
1回答

守候你守候我

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

相关分类

JavaScript