2017-03-18 72 views
0

這是我測試過的一段代碼,用於檢查是否可以使用setTimeout和clearTimeout停止for循環。 for循環保持運行。如何使用JavaScript中的Hotkey停止for循環

var ticket, key; 
$(document).on("keydown", function(e){ 
     if (e.key == "m") ticket = setTimeout(runMe,0); 
     if (e.key == "a") {clearTimeout(ticket); key = "a";} 
}) 

function runMe(){ 
for (var i=0; i < 1000000; i++){ 
if (key == "a") break; // doesn't work 
myFunct(i); 
} 
} 

function myFunct(i){ 
console.log(i); 
} 

var ticket, key, i=0; 
$(document).on("keydown", function(e){ 
     if (e.key == "m") ticket = setInterval(runMe,0,i++); 
     if (e.key == "a") {clearInterval(ticket); key = "a";} 
}) 

function runMe(i){ 
console.log(i); 
//myFunct(i); 

} 

function myFunct(i){ 
console.log(i); 
} 
+2

你不能。 Javascript是單線程的。直到你從Javascript返回到主事件循環,異步代碼纔會運行。 – Barmar

+0

有沒有其他的方法來完成這個? – user42826

+0

使用'setInterval()'重複運行代碼,'keydown'處理程序可以使用'clearInterval()'來停止它。 – Barmar

回答

1

,直到返回到主你不能停止異步代碼同步的代碼,因爲不執行異步代碼事件循環。

如果你想要週期運行的東西,用setInterval,然後將其清除事件發生時。

var counter = 0; 
 
var interval; 
 

 
function runMe() { 
 
    if (counter == 1000) { 
 
    clearInterval(interval); 
 
    } else { 
 
    counter++; 
 
    $("#output").text(counter); 
 
    } 
 
} 
 

 
$(document).on("keydown", function(e) { 
 
    if (e.key == 'm') { 
 
    interval = setInterval(runMe, 10); 
 
    } else if (e.key == 'a') { 
 
    clearInterval(interval); 
 
    } 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="output"></div>

1

也許你可以使用一個webworker運行的循環代碼,然後用terminate()停止循環。

// forloop.js 
for (var i=0; i < 1000000; i++){ 
    myFunct(i); 
} 

function myFunct(i){ 
    console.log(i); 
} 

// index.js 
var myWorker; 
$(document).on("keydown", function(e){ 
    if (e.key == "m") myWorker = new Worker('forloop.js'); 
    if (e.key == "a") {myWorker.terminate();} 
}) 

注:代碼沒有經過測試,只有給你粗略的概念

+1

明智的想法,一定會檢查出來 – user42826

+0

Upvote作爲一種方式來感謝;) – jperelli

0

JavaScript是單線程的,所以你的鍵盤處理將無法運行runMe()功能運行,直到完成後,直到。

您可以改爲使用setTimeout()(或setInterval())構建異步循環函數,以便其他代碼(如密鑰處理程序)有機會在「循環」迭代之間運行。

我建議封裝runMe()函數中的循環處理代碼,並讓runMe()返回一個可以調用的函數來停止當前循環。這樣,您可以輕鬆地同時使用多個不相關的循環,並獨立阻止它們 - 您需要跟蹤每個循環,而且我沒有在下面的代碼中顯示該循環,但它不僅僅是我所擁有的所示。 (如果使循環計數器一個全局變量,那麼顯然你不能有獨立的並行循環。)

var stopLoop; 
 

 
$(document).on("keydown", function(e){ 
 
    if (e.key == "m") stopLoop = runMe(); 
 
    if (e.key == "a") stopLoop(); 
 
}); 
 

 
function runMe(){ 
 
    var i=0; 
 
    var last=300; // I've used a smaller number so that you don't have to 
 
       // wait too long to see see that it stops by itself if 
 
       // you don't press "a" in the meantime 
 
    var stop = false; 
 
    
 
    (function looper() { 
 
    myFunct(i); 
 
    if (++i < last && !stop) 
 
     setTimeout(looper, 5); 
 
    })(); 
 
    
 
    return function() { stop = true; } 
 
} 
 
    
 
function myFunct(i){ 
 
    console.log(i); 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>