Pusher Websockets回调函数问题:JS新手每次仅打印ethbtc
解决WebSocket回调始终打印同一个交易对的问题
嘿,作为过来人太懂这种困惑了!你碰到的大概率是JavaScript闭包作用域或者变量覆盖的坑,我给你拆解几种最常见的场景和解决方案:
场景1:循环订阅多个交易对时的闭包陷阱
如果你的代码是类似这样循环创建WebSocket连接的:
const tradePairs = ["ethbtc", "btcusdt", "adausdt"]; for (var i = 0; i < tradePairs.length; i++) { const ws = new WebSocket(`wss://your-api.com/ws/${tradePairs[i]}`); ws.onmessage = function(event) { console.log(tradePairs[i]); // 结果每次都显示最后一个交易对,比如ethbtc }; }
问题出在var声明的i是函数作用域变量,所有回调函数共享同一个i。当onmessage触发时,循环早就跑完了,i的值已经变成了tradePairs.length,如果最后一个元素是ethbtc,就会一直显示它。
解决方案:
用let声明循环变量(块级作用域,每次循环都会创建新的变量),或者用forEach遍历:
// 方法1:用let for (let i = 0; i < tradePairs.length; i++) { const pair = tradePairs[i]; const ws = new WebSocket(`wss://your-api.com/ws/${pair}`); ws.onmessage = () => console.log(pair); } // 方法2:用forEach(更简洁) tradePairs.forEach(pair => { const ws = new WebSocket(`wss://your-api.com/ws/${pair}`); ws.onmessage = () => console.log(pair); });
场景2:全局变量被覆盖,没有绑定消息对应的交易对
如果你的代码依赖一个全局变量来存储当前交易对,比如:
let currentPair = ""; // 假设你有逻辑更新currentPair,但最后一次设置成了ethbtc currentPair = "ethbtc"; const ws = new WebSocket("wss://your-api.com/ws"); ws.onmessage = function(event) { console.log(currentPair); // 每次都拿最新的全局变量值 };
这种情况下,不管WebSocket收到的是哪个交易对的消息,都会打印最后一次赋值的currentPair。
解决方案:
从WebSocket返回的消息本身解析交易对,而不是依赖外部变量:
const ws = new WebSocket("wss://your-api.com/ws"); ws.onmessage = function(event) { const messageData = JSON.parse(event.data); // 假设消息里包含交易对字段,比如data.pair const pair = messageData.pair; console.log(pair); // 直接从消息中获取对应交易对 };
场景3:WebSocket连接被意外覆盖
如果你的代码把WebSocket实例赋值给了同一个变量,导致之前的连接被销毁:
let ws; const tradePairs = ["ethbtc", "btcusdt", "adausdt"]; tradePairs.forEach(pair => { ws = new WebSocket(`wss://your-api.com/ws/${pair}`); // 每次都覆盖ws变量 ws.onmessage = () => console.log(pair); });
这种情况下,只有最后一个创建的WebSocket连接(ethbtc)会保持活跃,之前的连接会被关闭,所以你只能收到ethbtc的消息。
解决方案:
把WebSocket实例保存在局部作用域或数组中:
const tradePairs = ["ethbtc", "btcusdt", "adausdt"]; const wsConnections = []; tradePairs.forEach(pair => { const ws = new WebSocket(`wss://your-api.com/ws/${pair}`); ws.onmessage = () => console.log(pair); wsConnections.push(ws); // 保存连接,避免被垃圾回收 });
你可以对照自己的代码看看属于哪种情况,应该就能解决问题啦!
内容的提问来源于stack exchange,提问作者user9357189
相关产品推荐
相关产品推荐

