如何在特定条件下停止JavaScript的服务器内容周期性轮询
解决leftHealth小于0时停止轮询的问题
已实现功能:
- 页面加载后每3秒轮询服务器,更新
leftHealth、leftEnergy、rightEnergy、turnMsg元素内容 - 监听
turnMsg元素,当内容包含“Stunned”或轮询计数达15时,等待4秒后刷新页面
需求补充:当leftHealth的值小于0时,停止所有周期性轮询及页面更新,节省带宽与数据库资源。
修改方案
核心思路是添加轮询控制开关,每次获取服务器响应后检查leftHealth的值,一旦小于0则关闭开关,不再发起下一次轮询;同时清理无效定时器,避免冗余执行。
修改后的完整代码
// On page load, instantiate a listener and begin polling the server for content. window.addEventListener('load', function(){ var xhr = null; // 轮询控制开关,初始允许轮询 let shouldPoll = true; function getXmlHttpRequestObject(){ if(!xhr){ // Create a new XMLHttpRequest object xhr = new XMLHttpRequest(); } return xhr; } function updateLiveData(){ // 开关关闭时直接终止请求发起 if (!shouldPoll) return; var now = new Date(); // Date string is appended as a query with live data to avoid caching issues var url = 'updatedVals.php?ID=' + ID + '&userName=' + userName + '&time=' + now.getTime(); xhr = getXmlHttpRequestObject(); xhr.onreadystatechange = eventHandler; // asynchronous requests xhr.open("GET", url, true); // Send the request over the network xhr.send(null); } updateLiveData(); function eventHandler(){ // Check response is ready or not if(xhr.readyState == 4 && xhr.status == 200){ let data = JSON.parse(xhr.responseText); ['leftHealth','leftEnergy','rightEnergy','turnMsg'].forEach(function(i){ document.getElementById(i).innerHTML = data[i] }); // 检查leftHealth是否小于0,触发停止轮询逻辑 if (parseInt(data.leftHealth) < 0) { shouldPoll = false; return; // 终止后续轮询设置 } // 开关开启时才设置下一次轮询 if (shouldPoll) { setTimeout(updateLiveData, 3000); // Update the live data every 3 sec } } } }); // Start listening for changes in the root HTML element of the page. mutationObserver.observe(document.documentElement, { attributes: true, characterData: true, childList: true, subtree: true, attributeOldValue: true, characterDataOldValue: true }); var counter = 0; // 重命名定时器变量,避免内部命名冲突 var refreshInterval = setInterval(function(){ // Evaluate the "turnMsg" document element we're evaluating and check for the string "Stunned". // But even if it does not show up, refresh the page about every minute or so. let s = document.getElementById('turnMsg').innerHTML; let result = s.includes("Stunned"); counter++; // If <div id="turnMsg"> contains "Stunned", wait 4 seconds then refresh. if ((result) || (counter == 15)){ clearInterval(refreshInterval); mutationObserver.disconnect(); // Stop the MutationObserver from listening for changes. // 用setTimeout实现4秒后刷新的逻辑 setTimeout(() => { location.reload(); // Reload the page. }, 4000); } }, 3000);
关键修改点
- 添加
shouldPoll变量作为轮询控制开关,初始值为true - 在
updateLiveData开头判断开关状态,关闭时直接终止请求发起 - 在
eventHandler中解析数据后,检查data.leftHealth的值,小于0则关闭开关并终止后续轮询 - 修复原代码中定时器变量命名冲突问题,用
refreshInterval替代i - 将原代码中空定时器替换为
setTimeout,实现4秒后刷新的合理逻辑
内容的提问来源于stack exchange,提问作者Camisade
相关产品推荐
相关产品推荐

