2017-03-18 16 views
0

ここでは、setTimeoutとclearTimeoutを使用してforループを停止できるかどうかをテストするコードを示します。 forループは、繰り返し実行されます。JavaScriptでホットキーを使用して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

たぶん、あなたはループを停止するterminate()を使用し、その後、ループのコードを実行するためにwebworkerを使用することができます。

// 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

アップウォートは感謝の方法;) – 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>

関連する問題