2016-12-15 11 views
0

私は、ボタンを押すたびに一度に1つずつランダムなシンボルをポップアップし、すべてのシンボルが読み込まれると読み込み可能な単語に変化するという関数を作成しています。遅れて働くことはできません。私はこれを終えることができないので、記号を読みやすい言葉に変える部分を加えました。forループ内のsetTimeoutが期待どおりに動作しない

//Brute Force 
function work() { 
    setTimeout(function() { 
     var $rand = Math.ceil(Math.random() * 10); 
     $('#txtBrute').append($sym[$rand]); 
    },1000); 
}; 
var i = 1; 
var $sym = [1,9,"%","$",")",">","@","?","-","|",7]; 
$('#btnBrute').click(function() { 
    var $pass = "password123"; 
    $('#txtBrute').html(""); 
    for(i = 1; i <= $pass.length; i++) { 
     work(); 
    }; 
}); 
+1

パス' i'と 'によって遅延を乗算私は。 – Teemu

答えて

3

あなたがループ内work()を呼び出しているので、問題があるので、すべてのタイマーはすぐに実行されます。

この代わりに、work()を再帰的にすることができます。パスワードの長さは、各再帰で減少値として使用できます。このお試しください:

var timeout; 
 
var $sym = [1, 9, "%", "$", ")", ">", "@", "?", "-", "|", 7]; 
 

 
function work(length) { 
 
    timeout = setTimeout(function() { 
 
    var $rand = Math.ceil(Math.random() * 10); 
 
    $('#txtBrute').append($sym[$rand]); 
 
    --length != 0 && work(length); 
 
    }, 1000); 
 
}; 
 

 
$('#btnBrute').click(function() { 
 
    clearTimeout(timeout); 
 
    var pass = "password123"; 
 
    $('#txtBrute').html(""); 
 
    work(pass.length); 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<button id="btnBrute">Go</button> 
 
<div id="txtBrute"></div>

をまた誰かが再帰ループがまだ実行されている間、ボタンを押し続けることを決定する必要があり、私はclearTimeout()呼び出しを追加したことに注意してください。

1

setTimeout()は、コードの残りの部分が実行されても影響を受けないため、ループは一度にすべてのタイムアウトを起動します。その結果、これらはすべて1000ミリ秒後に一度に呼び出されます。 Roryの答えは、work()を再帰的にすることを示唆しています。実装がおそらく容易しかしとして使用できないこの問題を解決する別の方法、あろうwork()に遅延量を渡す:work` `に

function work(delay) { 
 
    setTimeout(function() { 
 
     var $rand = Math.ceil(Math.random() * 10); 
 
     $('#txtBrute').append($sym[$rand]); 
 
    }, delay); 
 
}; 
 

 
var i = 1; 
 
var $sym = [1,9,"%","$",")",">","@","?","-","|",7]; 
 

 
$('#btnBrute').click(function() { 
 
    var $pass = "password123"; 
 
    $('#txtBrute').html(""); 
 
    for(i = 1; i <= $pass.length; i++) { 
 
     work(i * 1000); 
 
    }; 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<button id="btnBrute">Go</button> 
 
<pre id="txtBrute"></pre>

+0

これは機能しますが、ボタンが複数回クリックされた場合は、キューに入れられたすべてのタイマーを制御できないという欠点があります。作成時に配列に格納する必要があります。個々に消去してください。 –

+0

@RoryMcCrossan私はそれについては考えていませんでした。おそらく 'setInterval'を代わりに使うほうが簡単でしょう。再帰的に 'setTimeout'を使用する利点/欠点は何ですか? – ETHproductions

+0

間隔は、複数のボタンの押下の問題を解決します。タイマーが実行された回数を把握し、必要なときに停止するだけで済みます。 –

関連する問題