我有许多在迭代端口(端口4001、4002、4003等)上服务的socket.io服务器
我想使用循环将每个套接字客户端连接到相应的服务器:
connectSockets = (sensors) => {
const responses = {};
for (const [idx, sensor] of sensors.entries()) {
const socket = socketIOClient(`${endpointBase}:${port + idx}`);
socket.on(`From::${sensor}`, data => {
responses[sensor] = data
});
}
this.setState({
responses
});
};
当我在循环中中断时:
responses[sensor] = data
我可以看到数据。甚至将其分配给适当的“响应”属性。
但是,当我跳出循环并闯入setState时,我会看到:
responses = {}
不知道为什么。某种范围的问题?或者也许我对socket.io的工作方式感到困惑-第一次使用它。有趣的是,当我中断“ const socket”时,我得到了预期的三个迭代,但是当我中断了“ respons [sensor] = data”时,我得到了不止3次迭代。有人有什么想法吗?
答案 0 :(得分:2)
好吧,我自己弄清楚了。事实证明,这对socket.io的工作方式有误解。正如t.niese提到的,回调是异步的。
我需要做的是在套接字连接中设置状态,因为在循环完成时“数据”不一定可用:
socket.on(`From::${sensor}`, data => {
responses[sensor] = data
this.setState({responses});
});
工作完美。
答案 1 :(得分:0)
它不是您在问题(或答案)中所假设的范围界定问题,而是与何时执行部分代码有关。如果您放置一些console.log
(或代码中的断点),它将变得显而易见:
connectSockets = (sensors) => {
const responses = {};
console.log('before loop')
for (const [idx, sensor] of sensors.entries()) {
const socket = socketIOClient(`${endpointBase}:${port + idx}`);
socket.on(`From::${sensor}`, data => {
console.log(`socket.on callback for: ${sensor}`)
responses[sensor] = data
});
}
console.log('after loop')
this.setState({responses});
};
控制台中的输出或达到这些断点的顺序为:
before loop
after loop
socket.on callback for: ...
...
socket.on callback for: ...
在.on
中注册的事件处理程序在发生偶数时被调用,但是由于JavaScript不是多线程的,因此在向{{1 }}。
您可以通过将.on
移至事件回调来解决此问题(如您所知)。现在您可以多次调用this.setState({responses})
。如果出现问题,请取决于您的this.setState
函数。
答案 2 :(得分:0)
responses[sensor] = data
在随后的时间指针上异步触发。
this.setState({responses})
在同一事件循环中被调用。这就是为什么您找不到填充任何东西的原因。