如何实现无阻塞定时SQL查询及PHP分段返回内容?
哈哈,我来帮你一步步解决这两个头疼的问题!
一、先搞定JS循环:避免浏览器冻结的正确姿势
你之前写的while(true) { setTimeout(doRequest(), 10000); }完全是踩了大坑——这个while会瞬间无限循环,把无数个setTimeout塞进浏览器的事件队列,直接把主线程堵死,不冻结才怪!
正确的做法是用递归调用setTimeout,这样每次请求完成(或者到时间)后再安排下一次,不会堆积任务。另外你之前用window.onload等没生效,大概率是写法不对,给你两种靠谱的实现方式:
原生JS版本
// 确保DOM完全加载后再启动循环 document.addEventListener('DOMContentLoaded', function() { function doRequest() { // 这里写你的请求逻辑,比如用fetch或者XMLHttpRequest console.log('正在从数据库拉取数据...'); // 等当前请求完成后,再安排10秒后的下一次请求 setTimeout(doRequest, 10000); } // 启动第一次请求 doRequest(); });
jQuery版本
如果你习惯用jQuery,这样写更稳妥:
$(document).ready(function() { function doRequest() { $.post("../../modules/communicator.php", { action: "test" }, function(result) { console.log('请求结果:', result); // 请求成功后再触发下一次,避免请求堆积 setTimeout(doRequest, 10000); }); } doRequest(); });
⚠️ 注意:别用setInterval!如果某次请求因为网络慢超过10秒,setInterval会在10秒后强制发起新请求,导致多个请求同时跑,反而容易出问题。递归setTimeout是等上一次请求彻底结束后再等10秒,更安全。
二、PHP分段输出:让内容分批返回
你之前的PHP代码会一次性返回testhello,是因为PHP默认有输出缓冲机制——它会把所有echo的内容攒起来,直到脚本执行完才一起发给浏览器。要实现分段输出,得手动关掉缓冲并强制刷新:
修改后的PHP代码
<?php // 关闭默认的输出缓冲 ob_end_flush(); // 禁用PHP的输出缓冲设置 ini_set('output_buffering', 'off'); // 开启自动刷新,避免手动重复调用flush ini_set('implicit_flush', true); ob_implicit_flush(true); // 针对Nginx服务器,需要额外加这个头禁用fastcgi缓冲 header('X-Accel-Buffering: no'); if ($_POST['action'] == 'test') { echo "test"; // 强制把当前内容推送给浏览器 flush(); ob_flush(); // 等待5秒 sleep(5); echo "hello"; flush(); ob_flush(); } ?>
前端要配合接收分段内容
这里要注意:jQuery的$.post会等到整个响应完成才触发回调,看不到分段内容。必须用原生XMLHttpRequest监听progress事件:
function doRequest() { const xhr = new XMLHttpRequest(); xhr.open('POST', '../../modules/communicator.php'); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); // 监听进度事件,实时获取分段输出 xhr.onprogress = function(e) { if (e.lengthComputable) { console.log('当前已收到的内容:', xhr.responseText); } }; // 请求完成后的处理 xhr.onload = function() { console.log('请求全部完成,完整内容:', xhr.responseText); // 安排下一次请求 setTimeout(doRequest, 10000); }; // 发送请求数据 xhr.send('action=test'); }
这样前端就能在PHP输出test时立即收到,5秒后再收到hello啦!
内容的提问来源于stack exchange,提问作者user12457887
相关产品推荐
相关产品推荐

