简体   繁体   English

使用setTimeout进行AJAX Webworker轮询

[英]AJAX Webworker Polling with setTimeout

I'm trying to get a webworker to poll a web server interface on the same machine every second or so. 我正在尝试让网络工作者每秒钟左右轮询同一台计算机上的网络服务器接口。 Most articles I have read say to avoid setInterval and use setTimeout instead but I have yet to find an example that uses AJAX instead of Jquery. 我读过的大多数文章都说避免setInterval,而是使用setTimeout,但是我还没有找到使用AJAX而不是Jquery的示例。

The code I have so far is below: 我到目前为止的代码如下:

(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);
})();

The preferred output would be to poll the server each second which should in theory be more than adequate for the response to come through. 首选的输出将是每秒轮询服务器一次,从理论上讲,这应该足以使响应通过。 I only want one request on the go at a time so if I end up with a request taking more than a second it just dumps the request (rather than queuing it) and issues a new request. 我一次只需要一个请求,因此,如果我最终收到的请求花费了超过一秒钟的时间,它只会转储该请求(而不是对其进行排队)并发出一个新请求。

The above code polls okay but doesn't complete for 2 seconds so I've obviously got my setTimeout mixed up somewhere. 上面的代码可以轮询,但是2秒钟没有完成,所以我显然将setTimeout弄乱了。 Where do I correct this code? 我在哪里可以更正此代码?

Define a variable that determines if ajax finished or not. 定义一个确定ajax是否完成的变量。 If function is called while ajax hasn't finished yet, you can exit the function and wait for the next call. 如果在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);
})();

You can call same function when you get response of AJAX. 当您收到AJAX的响应时,可以调用相同的函数。 In this way no need to check that currently AJAX is in process or not. 这样,无需检查当前是否正在进行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);

If you want to use onload callback then callback code should be 如果要使用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);
    }

I did just that a few days ago.. and while it may not be the most elegant, it works fine so far. 几天前我就这样做了。虽然它可能不是最优雅的,但到目前为止效果还不错。 I have the worker handle the timeout / check interval, not the main JS. 我让工作人员处理超时/检查间隔,而不是主JS。 So I guess that's one more thing that the UI doesn't need to handle. 所以我想这是UI不需要处理的另一件事。 Here is my worker code: 这是我的工作人员代码:

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
};

Because you are using HTML5 WebWorker , probably, you can use window.fetch which uses promises ( https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API ), I think that browser support is almost the same. 因为您可能正在使用HTML5 WebWorker ,所以可以使用使用promises的window.fetchhttps://developer.mozilla.org/en-US/docs/Web/API/Fetch_API ),我认为浏览器支持几乎是相同。

Here is an example: 这是一个例子:

 ((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' }); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM