JavaScript实现点击按钮时检测REST接口返回数据是否重复
我明白你的问题啦——直接把data.results存到变量里之后,第二次比对总是不生效,对吧?这是因为在JavaScript里,数组和对象都是引用类型,你直接用===比较的是它们在内存中的地址,而不是实际的内容。哪怕两次返回的数据完全一样,它们也是两个不同的数组引用,所以比对结果永远是false。
接下来给你两种解决方案,分别适合不同场景:
方案1:用JSON序列化快速比对(简单易实现)
这种方法把数组转换成字符串,通过比对字符串是否相同来判断内容是否一致,适合你的数据结构(没有函数、undefined这类JSON无法序列化的内容)。
首先初始化一个变量来缓存第一次的序列化结果:
// 初始化为null,表示还没有缓存过数据 let cachedResultsStr = null;
然后在按钮点击的回调里这样处理:
function handleButtonClick() { // 这里替换成你调用REST接口的实际代码(比如fetch/axios) fetch('/your-api-endpoint') .then(response => response.json()) .then(data => { const currentResults = data.results; // 把当前结果序列化成字符串 const currentResultsStr = JSON.stringify(currentResults); if (!cachedResultsStr) { // 第一次获取数据:显示目标区域,缓存序列化后的结果 showYourTargetArea(); cachedResultsStr = currentResultsStr; } else { // 不是第一次,开始比对 if (currentResultsStr === cachedResultsStr) { // 数据完全相同,隐藏目标区域 hideYourTargetArea(); // 如果你需要实现「点击显示→再点相同隐藏→再点相同又显示」的切换效果,就加上下面这行 // cachedResultsStr = null; } else { // 数据不同:更新缓存,显示目标区域 showYourTargetArea(); cachedResultsStr = currentResultsStr; } } }) .catch(error => console.error('获取数据出错:', error)); } // 替换成你实际的显示/隐藏逻辑 function showYourTargetArea() { document.getElementById('your-target-element').style.display = 'block'; } function hideYourTargetArea() { document.getElementById('your-target-element').style.display = 'none'; }
方案2:自定义深度比对函数(更可靠)
如果你的接口返回的对象键顺序可能变化(比如某些后端返回的JSON键顺序不固定),或者未来数据结构有变化,JSON序列化的方法就可能失效。这时候可以写一个针对你数据结构的比对函数:
// 自定义比对函数:检查两个结果数组的内容是否完全一致 function areResultsEqual(arr1, arr2) { // 先比对数组长度,不一样直接返回false if (arr1.length !== arr2.length) return false; // 逐个比对数组里的每个对象 for (let i = 0; i < arr1.length; i++) { const item1 = arr1[i]; const item2 = arr2[i]; // 比对每个对象的三个属性 if (item1.Reqdate !== item2.Reqdate || item1.Tooltip !== item2.Tooltip || item1.Legendid !== item2.Legendid) { return false; } } // 所有属性都一致,返回true return true; }
然后修改按钮点击的逻辑:
let cachedResults = null; // 直接缓存原始数组 function handleButtonClick() { fetch('/your-api-endpoint') .then(response => response.json()) .then(data => { const currentResults = data.results; if (!cachedResults) { showYourTargetArea(); cachedResults = currentResults; } else { if (areResultsEqual(cachedResults, currentResults)) { hideYourTargetArea(); // 同样,需要切换效果的话就重置缓存:cachedResults = null; } else { showYourTargetArea(); cachedResults = currentResults; } } }) .catch(error => console.error('获取数据出错:', error)); }
最后提醒一下:如果你的需求是「每次点击相同数据就切换显示/隐藏状态」,记得在隐藏后把缓存变量重置为null,这样下一次点击就会重新触发显示逻辑啦。
内容的提问来源于stack exchange,提问作者user2644620
相关产品推荐
相关产品推荐

