如何在ThingsBoard JavaScript组件中阻塞func_1直至WebSocket消息接收?
如何阻塞func_1直到WebSocket收到消息
既然你明确表示不在意页面冻结,只需要保证func_1拿到WebSocket返回的字符串后再返回,让平台的func_2在它之后执行,那可以用同步循环等待的方案来实现——毕竟平台的do_some_things是同步调用这两个函数的,必须等func_1执行完毕返回值后才会触发func_2。
核心思路
利用一个标志变量标记WebSocket消息是否到达,然后用同步的while循环卡住主线程,直到消息到达后再继续执行并返回结果。虽然这种方式会冻结页面,但完全符合你“不在意站点冻结”的需求。
修改后的组件代码
//### WIDGET CODE (can modify!) ### function func_1() { let settings_string = null; let messageReceived = false; const socket = new WebSocket("ws://192.168.137.4:8081/"); // 监听WebSocket消息 socket.onmessage = function(evt) { settings_string = evt.data; messageReceived = true; // 收到消息后关闭连接,避免资源浪费 socket.close(); }; // 处理连接失败的情况,避免无限阻塞 socket.onerror = function() { messageReceived = true; settings_string = "default_settings"; // 可以设置默认值或者抛出错误 socket.close(); }; // 同步阻塞循环,直到消息收到或出错 while (!messageReceived) { // 空循环,持续占用主线程直到条件满足 } return settings_string; }
补充:增加超时保护(可选)
为了避免因为WebSocket连接异常导致无限阻塞,可以加入超时判断:
function func_1() { let settings_string = null; let messageReceived = false; const startTime = Date.now(); const timeoutMs = 10000; // 10秒超时 const socket = new WebSocket("ws://192.168.137.4:8081/"); socket.onmessage = function(evt) { settings_string = evt.data; messageReceived = true; socket.close(); }; socket.onerror = function() { messageReceived = true; settings_string = "default_settings"; socket.close(); }; // 带超时的阻塞循环 while (!messageReceived) { if (Date.now() - startTime > timeoutMs) { messageReceived = true; settings_string = "timeout_default"; socket.close(); break; } } return settings_string; }
注意事项
- 这种同步阻塞的方式会完全卡住浏览器主线程,期间页面无法响应任何点击、滚动或渲染更新,直到消息到达、超时或连接出错。
- 确保WebSocket服务器能稳定响应,否则过长的阻塞体验会很差(不过你已经说明不在意冻结,这点可以忽略)。
内容的提问来源于stack exchange,提问作者cyrili101
相关产品推荐
相关产品推荐

