我遇到回调函数的变量失去作用域的问题
. 我在数组中有以下 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 对象是否符合您的预期。
编辑
关于javascript - 回调函数缺少所需数据的范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50056226/