javascript - 回调函数缺少所需数据的范围

标签 javascript node.js sockets websocket

我遇到回调函数的变量失去作用域的问题

. 我在数组中有以下 2 个对象(简化以显示问题)

const search = [{socket: new WebSocket('ws://live.trade/123')}, 
                {socket: new WebSocket('ws://live.trade/xyz')}];

然后我对它们执行 forEach 以尝试在套接字打开后记录套接字 url。

search.forEach(function(element){
    element.socket.on('open', function open() {
      console.log(element.socket.url);
    });
});
*actual output*
ws://live.trade/xyz
ws://live.trade/xyz

*expected*
ws://live.trade/123
ws://live.trade/xyz

我觉得原因是当函数 open() 运行时,元素不在范围内,它只使用最后一个元素(即 ws://live.trade/xyz)。 它是否正确?最后,解决这个问题的方法是什么?这个的真正用途是当套接字打开时我需要通过调用它的套接字将版本数据发送到服务器......我实际上会有很多套接字并且不想写一个“socket.on('open '...)"对于每个单独的。

有什么建议吗?

非常感谢!

最佳答案

您的回调(即在 socket.on() 中)使用 forEach()element 变量。从您的实际结果来看,这可能意味着:

1。范围问题

由于 javascript/node 范围机制,变量可能在迭代中被“覆盖”,您提供的代码不是这种情况,但这是在循环内使用范围的常见问题。

在这种情况下你必须这样做:

search.forEach(function(element){
    element.socket.on('open', function(){
      console.log(this.socket.url);
    }.bind(element));
});

解释:

  • bind() 将其第一个参数(在本例中为 element 变量)作为其中的 this 传递给匿名函数。<
  • 在回调函数中,this.socket 在适当的迭代中等同于 element.socket

[UPDATE]Felix Kling 指出后, forEach() 为每个元素提供一个范围。

参见 bind更多细节。

2。依赖问题

如果这不是范围问题,则可能意味着您正在使用的库无法按预期工作。也许,尝试在 forEach() 中记录 element 以检查 WebSocket 对象是否符合您的预期。

编辑

  • 有关 Node/js 循环和引用的进一步阅读:参见 here
  • 对于一般的 Node/js 闭包:参见 here

关于javascript - 回调函数缺少所需数据的范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50056226/

相关文章:

Javascript Blob anchor 标签下载产生损坏的文件

c - 如何使用select同时读取连接?套接字/c

从单独的线程运行的Python ServerSocket

c - 监听系统调用中的积压值

javascript - 如何排除绑定(bind)故障

javascript - SVG Mask Transparent Circle - 只显示没有黄色背景的文本

javascript - Laravel Mix 和 Webpack : Cannot Load JSON File (Webpack Adding . js 到文件名)

javascript - 按相关性能问题排序

javascript - Electron - 如何使用主进程和渲染进程

javascript - this.property 在 nodejs 中返回 undefined