Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/450.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 回调函数缺少所需数据的作用域_Javascript_Node.js_Sockets_Websocket - Fatal编程技术网

Javascript 回调函数缺少所需数据的作用域

Javascript 回调函数缺少所需数据的作用域,javascript,node.js,sockets,websocket,Javascript,Node.js,Sockets,Websocket,我遇到了回调函数的变量丢失其作用域的问题 。 我在一个数组中有以下两个对象(简化以显示问题) const search=[{socket:newwebsocket('ws://live.trade/123')}, {socket:newWebSocket('ws://live.trade/xyz')}); 然后,我对它们执行forEach,试图在套接字打开后记录套接字url search.forEach(函数(元素){ on('open',function open(){ log(elemen

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

。 我在一个数组中有以下两个对象(简化以显示问题)

const search=[{socket:newwebsocket('ws://live.trade/123')},
{socket:newWebSocket('ws://live.trade/xyz')});
然后,我对它们执行forEach,试图在套接字打开后记录套接字url

search.forEach(函数(元素){
on('open',function open(){
log(element.socket.url);
});
});
我觉得原因是,当函数open()运行时,元素不在作用域中,它只使用上一个元素(即ws://live.trade/xyz)。 这是正确的吗?最后,解决这个问题的方法是什么?它的真正用途是当套接字打开时,我需要通过调用它的套接字将版本数据发送到服务器。。。现实中我会有很多套接字,我不想为每个套接字写一个“socket.on('open'…)”

有什么建议吗

非常感谢

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

1.范围问题 由于javascript/节点作用域机制,变量可能在迭代过程中被“重写”,您给出的代码并非如此,但在循环中使用作用域是一个常见问题

在这种情况下,您必须执行以下操作:

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

  • bind()
    将其第一个参数(本例中的元素变量)作为其内部的
    this
    传递给匿名函数
  • 在回调函数中,
    this.socket
    在适当的迭代中相当于
    element.socket
[UPDATE]在指出之后,forEach()为每个元素提供了一个作用域

有关更多详细信息,请参阅

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

编辑

  • 有关node/js循环和参考的更多信息,请参阅
  • 对于一般的节点/js闭包:请参见

您是正确的,
element.socket.url
将显示其最后一个值。我想你需要使用
这个
关键字。不太熟悉套接字,但类似于
this.url
的东西可能是“这正确吗?”不。JavaScript有词法范围。你在用哪个图书馆?我假设您使用的是一个,因为本机
WebSocket
实例没有
on
方法。我使用的是“ws:a NodeJS WebSocket library”“由于javascript/节点作用域机制,此变量在迭代过程中被覆盖。”这是不正确的。每个函数调用都有自己的作用域。证据:。你是对的!我将编辑我的答案,使其不那么“必要”。根据我的经验,我没有尝试就回答了这个问题,在这种情况下需要改进。。我是stackoverflow新手,我必须删除或编辑我的答案吗?将元素对象绑定到内部函数完成了这个技巧!为了更好地理解绑定函数,我将对其进行更多的阅读!非常感谢苏的帮助,也感谢@FelixKling@BrentAureli:虽然它可以工作,但您问题中的代码不可能有此问题,除非
WebSocket
已损坏(但GH上的代码看起来很好)或者您正在以某种方式更改数组中的对象。让我们试试更简单的。如果这样做会怎么样:
search.forEach(函数(元素){var socket=element.socket;socket.on('open',函数open(){console.log(socket.url);});})编辑答案以删除不正确的语句将是一个开始。您仍然可以保留您的解决方案作为可能的解决方法。
search.forEach(function(element){
    element.socket.on('open', function(){
      console.log(this.socket.url);
    }.bind(element));
});