为何计算Binance实时BTC价格之和时返回NaN?求排查
解决Binance WebSocket获取价格求和出现
NaN的问题 问题根源
出现NaN的核心原因有三个:
- 求和代码执行过早:你写的求和代码是页面加载时立即执行的,而
val1、val2要等2秒、3秒后才会被赋值,此时它们还是null,parseInt(null)返回NaN,相加结果自然也是NaN。 - 全局变量数据覆盖:
stockObject是全局变量,第一个setTimeout执行后会把它设为null,第二个setTimeout很可能拿不到有效数据,导致val2还是null。 - 类型转换错误:
toFixed(2)返回的是字符串,用parseInt转换会直接丢弃小数部分,应该用parseFloat处理价格数值。
修复后的代码
JavaScript代码
let ws = new WebSocket('wss://stream.binance.com:9443/ws/btcusdt@trade'); let stockPriceElementsec2 = document.getElementById('value1'); let stockPriceElementsec3 = document.getElementById('value2'); let resultElement = document.getElementById('result'); let lastPrice = null; // 用独立变量存储两次价格,避免数据覆盖 let price1 = null; let price2 = null; ws.onmessage = (event) => { const stockObject = JSON.parse(event.data); const currentPrice = parseFloat(stockObject.p); // 第一次获取价格时赋值给price1 if (!price1) { price1 = currentPrice; updatePriceDisplay(stockPriceElementsec2, price1); checkAndCalculateSum(); } // 第二次获取价格时赋值给price2 else if (!price2) { price2 = currentPrice; updatePriceDisplay(stockPriceElementsec3, price2); checkAndCalculateSum(); } // 如果需要持续更新价格,可在此添加后续逻辑 }; // 封装价格更新逻辑,减少重复代码 function updatePriceDisplay(element, price) { const formattedPrice = price.toFixed(2); element.innerText = formattedPrice; // 价格涨跌颜色判断 element.style.color = !lastPrice || lastPrice === formattedPrice ? 'black' : price > parseFloat(lastPrice) ? '#AAFF00' : 'red'; lastPrice = formattedPrice; } // 确保两个价格都存在时才计算求和 function checkAndCalculateSum() { if (price1 !== null && price2 !== null) { const total = price1 + price2; resultElement.innerText = total.toFixed(2); console.log('求和结果:', total.toFixed(2)); } }
HTML结构(无需修改)
<div class="container "> <div class="row"> <br /><br /> <div id="no-more-tables"> <table class="col-md-12 table-bordered table-striped table-condensed cf "> <thead class="cf"> <tr> <th>Current course</th> <th class="numeric w7 text-center">Value 1</th> <th class="numeric w7 text-center">Value 2</th> </tr> </thead> <tbody> <tr> <td>BTC</td> <td class="numeric"><span id="value1"></span></td> <td class="numeric"><span id="value2"></span></td> </tr> </tbody> </table> </div> </div> </div> <br /> <p>Sum : <span id="result"></span></p>
关键优化点
- 去掉全局
stockObject,改为在WebSocket消息回调内处理数据,避免数据被意外覆盖。 - 用
price1和price2分别存储两次价格,确保两个值都能正确获取。 - 只有当两个价格都赋值完成后才计算求和,从根源避免
NaN。 - 封装更新显示的函数,减少冗余代码,提升可维护性。
- 保留价格的小数部分计算,避免
parseInt导致的精度丢失。
内容的提问来源于stack exchange,提问作者elodie
相关产品推荐
相关产品推荐

