You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 02:15:41