ホームページ  >  記事  >  ウェブフロントエンド  >  暴走するJavaScriptループの問題を解決する

暴走するJavaScriptループの問題を解決する

黄舟
黄舟オリジナル
2016-12-15 10:49:081330ブラウズ

JavaScript は、クライアント側で Web ページに便利な制御をもたらします。その中で、制御不能なスクリプトは最も厄介な問題の 1 つです。

制御不能なスクリプトの主な原因の 1 つです。ループ内の実行が多すぎるということです。

ループ操作が制御不能になる理由は 2 つあります。1 つはループ操作が多すぎることです。もう 1 つはループが多すぎることです。この問題を解決するコツは次のとおりです。次の 2 つの質問を使用して各ループを評価します:

これ ループは同期的に実行する必要がありますか?

ループ内のデータは順番に実行する必要がありますか?

両方の質問に対する答えが「いいえ」の場合は、ループ内の操作を分解することを選択できます。重要なのは、コードの特定のコンテキストに基づいて、上記の 2 つの質問に対する答えを判断することです。典型的なループは次のようになります:

for(var i=0; i < items.length; i++){

process(items[i]);

}

一見すると、このループは次のように見えません。複雑すぎます。大きな問題は、実行に時間がかかるかどうかです。すべてはループの数によって決まります。ループの直後に実行されるときにループの結果に依存するコードが他にない場合、最初の質問に対する答えは「いいえ」です。また、ループでは一度に 1 つの値のみが処理され、前のループの結果に依存しないことがわかります。そのため、2 番目の質問に対する答えも「いいえ」です。これは、暴走したスクリプト メッセージでブラウザをロックしない方法でループを解消できることを意味します。

書籍『プロフェッショナル JavaScript 第 2 版』では、実行回数が非常に多いイリュージョンに対処するために次のメソッドを使用することをお勧めしています:

function chunk(array, process, context){

setTimeout(function( ) {

var item = array.shift();
process.call(context, item);

if (array.length > 0){

setTimeout(arguments.callee, 100);

}
}, 100 ) ;
}

chunk() 関数の目的は、配列を小さなチャンクに分割することです (これが名前の由来でもあります)。3 つのパラメーターを渡すことができます。処理される配列オブジェクト、処理関数、および process() 関数で対応するこのオブジェクトを設定するために使用されるオプションのコンテキスト変数。最初のタイマーは、操作間の遅延を処理するために使用されます (ここでは 100 ミリ秒に設定されていますが、実際のニーズに応じて変更できます)。この関数が実行されるたびに、配列内の最初のオブジェクトが取り出され、処理のために process() 関数に渡されます。この時点で process() 内にまだ処理されていないオブジェクトがある場合は、別の Use Waiting タイマーが開始されます。繰り返し。上記のループでは、次のメソッドでこの関数を使用できます:

chunk(items, process);

ここでの配列はキューの形式をとり、ループ中に毎回変更が発生することに注意してください。配列の元の状態を変更したい場合は、2 つの方法があります。1 つは、 concat() 関数を使用して、現在の配列を渡す前にそのコピーを作成する方法です:

chunk(items.concat(), process) ;

もう 1 つのオプションは、chunk() 関数を直接変更し、関数内で直接変更することです。 setTimeout(function () () {

var item = items.shift ();

proces.call (context, item);

if (items.length & gt; 0) {
Settimeout (Arguments.callee, 100) ;
}
}, 100);
}

次のタイマーが有効になる前に配列の内容が変更される可能性があるため、この方法は単にインデックスを保存するよりもはるかに安全であることに注意してください。

ここで説明した chunk() 関数は、ループのパフォーマンスを最適化するための開始点にすぎません。必要に応じて、さらに機能を追加するために改良を続けることができます。たとえば、配列内のすべてのオブジェクトが処理された後、関数コールバックを追加できます。この方法で関数を変更するかどうかに関係なく、これは配列処理のパフォーマンスを最適化し、スクリプトが制御不能になっているという警告を回避するのに役立つ単なる JavaScript コード開発モデルです。

上記は制御不能な JavaScript ループの問題の解決策です。その他の関連記事については、PHP 中国語 Web サイト (www.php.cn) に注目してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。