2014-02-26 44 views
3

如果我不想處理數據,並且稍後再嘗試一次,如果我想暫停Web工作人員,該怎麼辦?我能以這種方式在網絡工作者那裏做到這一點嗎?來自網絡工作者的setTimeout

var doStuff = function() { 
    if(databaseBusy()) { 
     setTimeout(doStuff, 1000); 
    } else { 
     doStuffIndeed(); 
    } 
} 

我得到未捕獲的RangeError:最大調用堆棧大小超過和東西告訴我這是因爲上面的代碼。

+0

爲什麼不使用'setInterval()'而不是如果你想重複? – Lloyd

+0

當數據庫停止繁忙時,我想停止它。 –

+1

@MishaSlyusarev然後在條件滿足後使用'clearInterval()'。 – Sirko

回答

2

如果「暫停」你的意思是「還呼籲worker.postMessage()將得到排隊,而不是由工人加工」,則沒有,你不能使用setTimeout()這一點。 setTimeout()不是一個忙碌的等待,而是一個延遲工作直到後來的預定時間的線程內機制。網絡工作者在發佈後仍會從主隊列中收到新的onmessage事件。

但是,您可以執行的操作是手動排隊,然後使用setTimeout嘗試稍後處理它們。例如:

worker.js

var workQueue = []; 
addEventListener('message',function(evt){ 
    workQueue.push(evt.data); 
    doStuff(); 
},false); 

function doStuff(){ 
    while (!databaseBusy()) doStuffIndeed(workQueue.shift()); 
    if (workQueue.length) setTimeout(doStuff,1000); 
} 
  • 每接收到一個消息的工作並將其放入一個隊列,並調用tryToProcess時間。
  • tryToProcess只要數據庫可用,就一次從隊列中取出一條消息。
  • 如果數據庫不可用並且有留言,則會在1秒內再次嘗試。
+0

那麼我的工作人員將收到一條消息,從數據庫獲取數據,處理加載的數據,並將結果發回主線程。我只想暫停直到數據庫可供閱讀。 –

+0

@MishaSlyusarev然後這個解決方案對你來說很好,即使隊列只有空的或有一個項目。當你在等待處理第一個數據時,你確定第二個數據請求不會進入嗎? – Phrogz

+1

但是,如果您真的只會有一個請求在飛行中,那麼您的原始解決方案應該工作得很好。它不會導致尾部調用或使用任何遞歸,只要你已經寫了它,並且不要**'setTimeout(doStuff(),1000)'(帶函數調用中的父類)。 – Phrogz