Twitch API轮询结果对比失效求助:变量作用域排查
问题分析与解决方案
你的对比功能失效主要有三个核心问题:变量作用域导致上一次的结果无法持久化、对象引用对比逻辑错误,以及定时器调用逻辑混乱。咱们一步步拆解并修复:
1. 核心问题拆解
(1)previousResponse 无法持久化
你在displayViewers函数内部重新声明了const previousResponse = usersInChannel.data.chatters.viewers,这是一个局部变量,会覆盖函数参数;而且每次调用displayViewers()时都没有传入上一次的结果,导致每次对比的previousResponse要么是undefined,要么是当前这次的对象,根本没法做跨轮询的对比。
(2)对象直接用===对比无效
JavaScript中,===对比对象时,只会检查两个变量是否指向同一个内存引用,而不是对比对象的内容。哪怕两次API返回的viewers内容完全一样,它们也是两个不同的对象,===会返回false,这直接导致你的对比逻辑完全失效。
(3)无意义的intervalFunction调用
你的代码里没有定义intervalFunction,而且原本已经用setInterval做了轮询,这里的调用属于冗余且错误的逻辑。
2. 修复后的完整代码
// 持久化存储上一次的API结果,放在全局/模块作用域里 let previousViewers = null; // 格式化打印JSON function prettyJSON(obj) { console.log(JSON.stringify(obj, null, 2)); } // 获取Twitch聊天用户列表 const getUsers = async () => { try { return await axios.get("http://tmi.twitch.tv/group/user/sixteenbitninja/chatters"); } catch (error) { console.error(error); return null; // 出错时返回null,避免后续报错 } }; // 深对比两个对象的内容(针对viewers这种简单对象) const areObjectsEqual = (obj1, obj2) => { if (obj1 === obj2) return true; if (typeof obj1 !== 'object' || obj1 === null || typeof obj2 !== 'object' || obj2 === null) { return false; } const keys1 = Object.keys(obj1); const keys2 = Object.keys(obj2); if (keys1.length !== keys2.length) return false; for (const key of keys1) { if (!keys2.includes(key) || !areObjectsEqual(obj1[key], obj2[key])) { return false; } } return true; }; // 处理并对比结果 const displayViewers = async () => { const usersResponse = await getUsers(); if (!usersResponse?.data?.chatters?.viewers) { console.log("Failed to get valid viewers data"); return; } const currentViewers = usersResponse.data.chatters.viewers; // 第一次轮询时,直接保存结果并打印 if (previousViewers === null) { console.log("Initial viewers data:"); prettyJSON(currentViewers); previousViewers = currentViewers; return; } // 用深对比判断内容是否一致 if (areObjectsEqual(currentViewers, previousViewers)) { console.log("The objects are the same"); } else { console.log("Updated viewers data:"); prettyJSON(currentViewers); previousViewers = currentViewers; // 更新上一次的结果 } }; // 每5秒轮询一次 const interval = setInterval(displayViewers, 5000);
3. 关键修改说明
- 持久化变量:把
previousViewers放在函数外部的作用域(全局或模块作用域),这样每次轮询都能保留上一次的结果。 - 深对比函数:实现了
areObjectsEqual来递归对比对象内容,替代原来的引用对比。如果你的viewers结构很简单(只是键值对),也可以用JSON.stringify(obj1) === JSON.stringify(obj2),但要注意这种方法对某些特殊值(比如undefined、函数)处理有限,递归对比更可靠。 - 简化定时器逻辑:直接把
displayViewers传给setInterval,不需要额外的匿名函数包裹,避免逻辑混乱。 - 增加错误处理:在获取API结果时增加了空值判断,避免因API返回异常导致后续代码报错。
内容的提问来源于stack exchange,提问作者Mike Nedelko
相关产品推荐
相关产品推荐

