Array.push覆盖数组原有值而非新增,去重逻辑下不生效问题
问题原因
- 变量声明不规范:代码中
length = socketarray.push(...)没有加var/let/const关键字,会隐式创建全局变量,若其他逻辑修改了该全局变量,可能连带影响数组操作。 - 匹配判断逻辑有类型兼容问题:
findIndex中用==做相等判断,如果parsed_result返回的car_id和数组中存储的car_id类型不一致(比如一个是数字、一个是带特殊字符的字符串),会导致判断结果不符合预期:要么每次都判定为不存在重复但实际car_id相同,要么每次都判定为已存在导致后续数据无法推入,看上去像是之前的数据被覆盖。 - 控制台打印的延迟求值坑:直接打印数组对象时,浏览器/Node.js控制台不会保存数组快照,展开时才会读取最新值,容易误导你以为之前的元素被覆盖。
- 高频事件的竞态风险:
data事件触发频率很高,回调函数标记了async但内部无异步操作时暂不影响,后续如果加入异步逻辑,多个回调并发执行时容易出现判断异常。
修复方案
优先用Set做已存在id的判重,比数组findIndex效率更高,也能规避类型判断的问题:
var socketarray = []; // 新增Set存储已存在的car_id,统一转字符串存储避免类型问题 var existedCarIds = new Set(); socket.on('data', async data => { var server_data = data.toString(); var parsed_result = m.parsingData(server_data); if (parsed_result) { // 统一转成字符串,避免类型不一致导致的判断错误 var car_id = String(parsed_result.car_id); // 直接用Set判断是否存在,O(1)效率 if (!existedCarIds.has(car_id)) { existedCarIds.add(car_id); socketarray.push({ "car_id": car_id }); // 打印JSON快照,避免控制台延迟求值的误导 console.log("新增成功,当前数组:", JSON.stringify(socketarray, null, 2)); } else { console.log("already present,当前car_id:", car_id); console.log("当前数组:", JSON.stringify(socketarray, null, 2)); } } });
异常现象解释
把push放在判重逻辑前时,所有数据都会无条件推入数组,不会被有问题的判重逻辑拦截,所以能存入多条数据,只是会出现重复。放在判重逻辑后无法存入,本质是判重逻辑的判断结果不符合预期,导致后续的push没有执行,并非push操作覆盖了已有数据。
内容的提问来源于stack exchange,提问作者mynameisbutt
相关产品推荐
相关产品推荐

