我正在尝试让网络工作者每秒钟在同一台机器上轮询一个Web服务器界面。我读过的大多数文章都说要避免使用setInterval并使用setTimeout,但我还没有找到一个使用AJAX而不是Jquery的例子。
我到目前为止的代码如下:
(function poll() {
setTimeout(function() {
var xhr = new XMLHttpRequest();
xhr.onload = function() {
if (xhr.status === 200) {
responseObject = JSON.parse(xhr.responseText);
var newContent = '';
newContent += responseObject.cmd;
console.log(newContent);
}
}
xhr.open('GET', 'http://localhost:8194/screen_update/1000', true);
xhr.send(null);
setTimeout(poll, 1000);
}, 1000);
})();
首选输出是每秒轮询一次服务器,理论上这应该足以让响应通过。我一次只想要一个请求,所以如果我最终得到一个请求超过一秒钟它只是转储请求(而不是排队)并发出新的请求。
上面的代码轮询没问题,但是没有完成2秒,所以我显然让我的setTimeout在某处混淆了。我在哪里更正此代码?
答案 0 :(得分:0)
定义一个确定ajax是否完成的变量。如果在ajax尚未完成时调用函数,则可以退出该函数并等待下一次调用。
var stillWorking = false;
(function poll() {
if(stillWorking) return false;
stillWorking = true;
setTimeout(function() {
var xhr = new XMLHttpRequest();
xhr.onload = function() {
if (xhr.readyState == 4) stillWorking = false;
if (xhr.status === 200) {
responseObject = JSON.parse(xhr.responseText);
var newContent = '';
newContent += responseObject.cmd;
console.log(newContent);
}
}
xhr.open('GET', 'http://localhost:8194/screen_update/1000', true);
xhr.send(null);
setTimeout(poll, 1000);
}, 1000);
})();
答案 1 :(得分:0)
当您收到AJAX的响应时,您可以调用相同的函数。这样就无需检查当前的AJAX是否正在进行中。
function poll() {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange= function() {
if (xhr.status === 200) {
responseObject = JSON.parse(xhr.responseText);
var newContent = '';
newContent += responseObject.cmd;
console.log(newContent);
}
if (xhr.readyState == 4)
{
setTimeout(function(){ poll();},1000);
}
}
xhr.open('GET', 'http://localhost:8194/screen_update/1000', true);
xhr.send(null);
};
setTimeout(function(){ poll();},1000);
如果你想使用onload回调,那么回调代码应该是
xhr.onload= function() {
if (xhr.status === 200) {
responseObject = JSON.parse(xhr.responseText);
var newContent = '';
newContent += responseObject.cmd;
console.log(newContent);
}
setTimeout(function(){ poll();},1000);
}
答案 2 :(得分:0)
我几天前做过这样的事情..虽然它可能不是最优雅的,但它到目前为止还能正常工作。 我有工作人员处理超时/检查间隔,而不是主JS。所以我猜这是用户界面不需要处理的另一件事。这是我的工人代码:
function checkStatus() {
console.log("statusCheck started");
var ajaxRequest;
try { ajaxRequest = new XMLHttpRequest(); // Opera 8.0+, Firefox, Safari
} catch (e) { try { // Internet Explorer Browsers
ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) { try {
ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) { // Something went wrong
console.error("AJAX not possible");
return false;
}
}
}
// Create a function that will receive data sent from the server
ajaxRequest.onreadystatechange = function() {
if(ajaxRequest.readyState == 4) {
self.postMessage(ajaxRequest.responseText);
var timer;
timer = self.setTimeout(function(){
checkStatus();
}, 1000);
}
}
ajaxRequest.open("GET", "/worker_statusCheck.php", true);
ajaxRequest.send(null);
}
this.onmessage = function(e){
checkStatus(); // the message comes in just once on pageLoad
};
答案 3 :(得分:0)
因为您使用HTML5 WebWorker
,可能使用使用promises()的window.fetch
,我认为浏览器支持几乎相同。
以下是一个例子:
((url, INTERVAL, configs) => {
const MAX_ERRORS = 4;
let errors = 0;
var poll = () => window.setTimeout(getData, INTERVAL);
function getData() {
return window
.fetch(url, configs)
.then(res => res.json())
.then(data => {
errors = 0;
poll();
return data;
})
.then((data) => {
console.log("new data available", data);
})
.catch(() => {
if(errors >= MAX_ERRORS) {
console.log("GIVING UP");
return;
}
errors += 1;
return poll();
})
;
}
return poll();
})("http://jsonplaceholder.typicode.com/posts/1", 1000, {
method: 'GET'
});