我遇到了回调函数失去其范围的变量的问题
。 我在数组中有以下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 ('开' ...)"对于每个人。
有什么建议吗?
非常感谢!
答案 0 :(得分:1)
您的回调(即socket.on())使用element
的{{1}}变量。根据您的实际结果,它可能意味着:
变量可以是" 覆盖"由于javascript / node scope机制,在迭代中,你给出的代码不是这种情况,但是在循环中使用范围是一个常见的问题。
在这种情况下你必须这样做:
forEach()
说明:
search.forEach(function(element){
element.socket.on('open', function(){
console.log(this.socket.url);
}.bind(element));
});
将其第一个参数(在本例中为元素变量)传递给其中的bind()
匿名函数。this
在适当的迭代时相当于this.socket
[更新] 在Felix Kling指出之后,forEach()为每个元素提供了一个范围。
有关详细信息,请参阅bind。
如果它不是范围问题,则可能意味着您使用的库无法按预期工作。也许,尝试在forEach()中记录element.socket
以检查 WebSocket 对象是否符合您的预期。
修改强>