2017-12-08 19 views
1

私はそれJavascriptをarray.forEach(機能)予想の2倍の数倍

<!DOCTYPE html> 
<html> <body> 
<p>Click the button to list all the items in the array.</p> 

<button onclick = "numbers.forEach(myFunction)" >Try it</button> 

<p id="demo"></p> 
</body>  
</html> 

上の単一のボタンでhtmlファイルを持っている機能を実行し、私も.forEachメソッドのonclick機能を含むのJavascriptファイルを持っています。
ボタンをクリックすると、配列内の要素の各インスタンスをループする配列を調べたいと思います。

この配列のすべての要素について、次の並べ替えを表示するのを待ってから、そのインデックスと値を後でタイマーで出力したいと思います。私は、ユーザーがボタンをクリックしたときに表示するように結果が欲しい何

demoP = document.getElementById("demo"); 
var numbers = []; 

var random = Math.floor(Math.random() * 4) + 1; 

numbers.push(random); 

function myFunction(item, index) { 
    random = Math.floor(Math.random() * 4) + 1; 
    numbers.push(random); 
    demoP.innerHTML = demoP.innerHTML + "numbers[" + index + "]: " + item + "<br>"; 
    //demoP.innerHTML = demoP.innerHTML + "<br>" //add magic spacing between permutation 
    sleep(100); 
    //switch to this and see how slow? 
    //sleep(1000); 
} 

function sleep(milliseconds) { 
    var start = new Date().getTime(); 
    for (var i = 0; i < 1e7; i++) { 
    if ((new Date().getTime() - start) > milliseconds){ 
     break; 
    } 
    } 
} 

は次のとおりですので、上の

numbers[0] = 4 
//waits a second and adds a <br> here to separate 
numbers[0] = 4 
numbers[1] = 2 
//waits a second and adds a <br> here 
numbers[0] = 4 
numbers[1] = 2 
numbers[2] = 3 

と。

現在、コードは少なくとも2倍の要素を出力し、sleep()はそれよりも長く持続するようです。

+4

「スリープ」機能を追加しないでください。その代わりに、 'setTimeout'や' setInterval'のようなものを通してasyc呼び出しを行う方法を学んでください。また、実行時にコードを追跡するために 'console.log'を使用することを検討してください。 'forEach'を実行している間に配列' numbers'を変更しているので、問題を尋ねています。また、DOM要素の 'onclick'属性内で' forEach'を実行することは、最善の方法ではありません。 onclickに関数を呼び出し、その関数で 'forEach'を実行します。 – Intervalia

+0

@Intervalia私はそのインターバル時間に問題がありました。そのため、 'setTimeout'または 'setInterval'を使用する代わりに、テストするために 'sleep()'を作成しました。 – Jamin

+0

@ジャミン私は私の答えで間違いを犯しました。新しい更新されたものをお読みください。ごめんなさい! –

答えて

4

厄介なsleep機能とは別に、 myFunctionをコールバックのforEachとして使用し、myFunctionにはnumbers(これはforEachと同じ配列)を押しています。

forEachは、配列をループしながら新しくプッシュされたアイテムに対してコールバックを呼び出しません。しかし、ループの最後まで、配列内の項目は2倍になります。 MDNに係るとおり

forEach()によって処理要素の範囲は、callbackの最初の呼び出しの前に設定されています。 forEach()への呼び出し後に配列に追加される要素は、callbackでアクセスされません。

配列はN要素、クリックが発生したときに、N要素が表示されます、そしてmyFunctionN他の要素をプッシュすると、次のクリックが発生したとき2N要素は、この時間が表示されますが、含まれている場合...

クリックするたびに、配列内の要素が2倍になります。