2011-09-07 70 views
2

作爲一個教育項目,我正在編寫(另一種)JavaScript編輯器式的實時語法突出顯示器。Javascript併發控制

爲了保持編輯器響應,我顯然選擇讓熒光筆異步運行,但是對於我使用的模型,如果在當前的熒光筆完成之前鍵入內容,則需要在啓動另一個熒光筆之前終止熒光筆,並且知道它在新手開始之前就已經結束了。

我的想法做一些類似下面的:

var terminate = false; 
var terminated = false; 

function work() { 
    while(!terminate) 
    console.log('working'); 
    terminated = true; 
} 

function stop() { 
    terminate = true; 
    while(!terminated); 
    console.log('stopped'); 
} 

setTimeout(work, 0); 
setTimeout(stop, 10); 

這個例子不過是不行的,我已經到位忙望眼欲穿的使用更多的下一個定時器,試過了,無論是。

有沒有一種方法可以在JavaScript中實現這樣的系統,還是我應該使用一些替代方法(或兩者)?

回答

8

如果您可以在沒有DOM訪問權限的情況下完成大部分工作,那麼對於網絡工作者來說,這是完美的。

要修復您的示例,請嘗試使用setTimeout0進行產生控制。這工作:

var terminate = false; 
var terminated = false; 

function work() { 
    if(!terminate) { 
    console.log('working'); 
    setTimeout(work, 0); 
    } 
    else terminated = true; 

} 

function stop() { 
    terminate = true; 
    if(!terminated) { 
     setTimeout(stop,0); 
    } 
    else console.log('stopped'); 
} 

setTimeout(work, 0); 
setTimeout(stop, 100); 

編輯

與原來的代碼片段解釋這個問題:JavaScript是單線程的(除非您使用網絡工作者)。您可以使用事件,回調和setTimeout來達到併發的幻覺,但是您真正在做的是告訴運行時在單個執行線程上的將來某個時間執行回調函數。在你的情況下,stop永遠不會被執行。 10毫秒過期後,它被安排運行「下一步」(即work結束後,由於work永遠不會結束,stop永遠無法運行。

所以你想離開的JavaScript任何明顯的併發性將是合作你的工作線程將不得不暫停,並明確允許「其他的東西」發生,以保持幻想

+0

啊,這確實有用,不知道我必須做些什麼:/儘管不應該'終止=真;'在'else'而不是'if',以防止不必要的setTimeout? – connec

+0

是的,那會更好。固定。 –

2

在這種情況下,考慮使用Workers大多數現代瀏覽器支持他們。 javascript(這是很好的) - 全部在一個線程中完成。

很多setTimeout()電話是一個殺手。