Node.js Express中使用Proxy监听器时req.query.id值被覆盖问题求助
问题解析:为何两次输出均为
current b? 代码示例
let observe = (obj: any, fn: any) => new Proxy(obj, { set: (obj, key, val) => { fn(obj) return obj[key] = val; } }); router.use('/', async (req, res) => { const id = req.query.id arrs = observe([], (arr: any) => { console.log("current", id) }); setTimeout(() => { arrs.push(id); }, 5000); }
问题现象
代码功能整体正常,但console.log("current", id)输出不符合预期:
- 第一步:访问
http://localhost:9000/?id=a - 第二步:1秒后访问
http://localhost:9000/?id=b - 第三步:5秒后,两次请求的
setTimeout触发,控制台输出:
current b current b
预期输出应为:
current a current b
核心原因
1. 全局变量arrs导致实例覆盖
你代码中的arrs是全局变量,第二次请求(id=b)进来时,会直接将第一次请求创建的Proxy实例覆盖。等到5秒后,两个setTimeout触发时,操作的都是第二次请求创建的Proxy实例,第一次的实例已经被丢弃。
2. 闭包捕获变量引用而非值
Proxy的回调函数(arr: any) => {console.log("current", id)}捕获的是id变量的引用,而非创建时的具体值。由于第二次请求的Proxy实例覆盖了全局的arrs,当两个setTimeout执行push操作时,触发的都是第二个Proxy的set方法,该回调绑定的是第二次请求的id(值为b),所以两次输出都是current b。
修复方案
将arrs改为请求处理函数内的局部变量,确保每个请求拥有独立的Proxy实例,避免全局覆盖:
let observe = (obj: any, fn: any) => new Proxy(obj, { set: (obj, key, val) => { fn(obj) return obj[key] = val; } }); router.use('/', async (req, res) => { const id = req.query.id; // 改为局部变量,每个请求创建独立的Proxy实例 const arrs = observe([], (arr: any) => { console.log("current", id); }); setTimeout(() => { arrs.push(id); }, 5000); // 务必返回响应,避免请求挂起 res.send('请求已接收'); });
修改后,两次请求会创建各自独立的arrs和回调函数,5秒后分别触发对应的set方法,输出符合预期的current a和current b。
内容的提问来源于stack exchange,提问作者ali
相关产品推荐
相关产品推荐

