2016-07-25 61 views
1

我试图让webworker每隔一秒钟在同一台计算机上轮询Web服务器接口。我读过的大多数文章都说避免setInterval并使用setTimeout,但我还没有找到使用AJAX代替Jquery的示例。AJAX Webworker使用setTimeout轮询

我到目前为止的代码如下:

(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

把超时的onoad – epascarello

回答

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

这将停止Ajax请求,如果状态码不是200 –

+0

喔,是的......我们必须检查如果状态为4,则为ajax状态。 –

+0

我修改了代码。 –

0

我只是前几天..虽然它可能不是最优雅的,它工作正常等等远。 我有工人处理超时/检查间隔,而不是主要的JS。所以我想这是UI不需要处理的一件事。这里是我的工人代码:

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

顺便说一句:这不会检查每一秒。这会再次检查一次AFTER成功的AJAX响应。 –

0

由于您使用HTML5 WebWorker,或许,你可以使用window.fetch它使用的承诺(https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API),我认为浏览器的支持几乎是一样的。

下面是一个例子:

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