0

このコードはクロムをクラッシュさせます:

 var ms = 1000;

 function wait(ms) {

     function _done() {
         done = true;
         alert('timer: ' + timer + ', done: ' + done);
         clearTimeout(timer);
     }

     var done = false;
     var timer;
     alert('starting timer');
     while (!done) {
         timer = setTimeout(_done, ms);
     }
     alert('wait done');
 }

なんで?どうすればこれを正しく理解できますか?

4

3 に答える 3

0

ここには多くの基本的な問題があります。

まず、コードに描かれていない場所で、実際にwait関数を渡して呼び出していると想定していますms

done変数が必要で、 functionでtimerアクセスできるように見えます_done。そのためには、関数を定義する前に変数を初期化する必要があります。

setTimeout非同期です。わざわざ他のスレッド (Web ワーカー) を起動しない限り、Javascript はシングル スレッドです。一定時間setTimeout処理をフリーズしません。ms他に何も実行されていない場合に実行されるイベントを追加します。ブロックされていないため、while ループは再びループして別のタイムアウトを作成し、別の...無限大です。while ループはシングル スレッドであるため、多数のタイムアウトが発生しても while ループが中断されることはありません。これは、Windows メッセージ キューに似ています。_done中断せずに true に設定されるためdone、必然的なクラッシュが発生するまで、ますます多くのタイムアウトが継続的にスピンオフされます。

コードの実行を一定時間遅らせたい場合は、setTimeout一度実行すると、他に何も実行されていない限り待機してから実行が開始されます。

function _done() {
  alert('done!');
}

setTimeout(_done, 1000);

clearTimeout別の注意点として、すでにタイムアウトになっているタイムアウトについては、その必要はないと思います。タイムアウトになる前にタイムアウトが発生するのを防ぐためにのみ使用されます。これは、10 回のうち 9 回は、setTimeout の戻り値を無視できることを意味します。

于 2013-10-02T15:17:07.340 に答える