AJAX Webworker使用setTimeout进行轮询

时间:2016-07-25 13:36:11

标签: javascript ajax settimeout web-worker polling

我正在尝试让网络工作者每秒钟在同一台机器上轮询一个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在某处混淆了。我在哪里更正此代码?

4 个答案:

答案 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(enter image description here)的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' 
});