2016-07-25 91 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' 
 
});