ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript クライアントはアップロードされた画像のサイズを検証します (IE および Firefox と互換性があります)_JavaScript スキル

JavaScript クライアントはアップロードされた画像のサイズを検証します (IE および Firefox と互換性があります)_JavaScript スキル

WBOY
WBOYオリジナル
2016-05-16 18:48:131035ブラウズ

前回の投稿 (翻訳) では、各ブラウザが制御不能なスクリプト プロンプトを表示する状況について説明しました。Internet Explorer の場合、ブラウザが実行するステートメントが多すぎると、他のブラウザではスクリプトの実行が停止されます。スクリプトが一定期間以上実行され続けるとプロンプトが表示されます。私たちが議論したい中心的な問題は、これらのブラウザが暴走スクリプトをどのように検出するかではなく、これらの警告を回避するためにスクリプトの実行を高速化する方法です。
スクリプトが制御不能になる理由は基本的に 4 つあります。
ループ内で実行される操作が多すぎます。
関数本体の肥大化
再帰が多すぎます
DOM 呼び出しが多すぎます
この投稿では、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);
}
},
}

chunk() 関数の目的は、配列を小さな部分に分割して処理することです (これが名前の由来でもあります)。3 つのパラメーターを渡すことができます。処理される配列オブジェクト、処理関数、および process() 関数で対応するこのオブジェクトを設定するために使用されるオプションのコンテキスト変数。最初のタイマーは、操作間の遅延を処理するために使用されます (ここでは 100 ミリ秒に設定されていますが、実際のニーズに応じて変更できます)。この関数が実行されるたびに、配列内の最初のオブジェクトが取り出され、処理のために process() 関数に渡されます。この時点で process() にまだ未処理のオブジェクトがある場合は、Waiting を使用して別のタイマーが開始されます。繰り返し。上記のループでは、次のメソッドでこの関数を使用できます:
chunk(items, process);
ここでの配列はキューの形式をとり、ループ プロセス中に変更が発生することに注意してください。毎回。配列の元の状態を変更したい場合は、2 つの方法があります。1 つは、 concat() 関数を使用して、現在の配列を渡す前にそのコピーを作成する方法です。
chunk(items.concat(), process) );
もう 1 つのオプションは、chunk() 関数を直接変更し、関数内で直接変更することです:
コードをコピーします コードは次のとおりです:

function chunk(array, process, context){
var items = array.concat(); // 配列のクローンを作成します
setTimeout(function( ){
var item = items.shift();
process.call(context, item);
if (items.length > 0){
setTimeout(arguments.callee, 100) ;
}
}、100)
}

次のタイマーが有効になる前に配列の内容が変更される可能性があるため、この方法は単にインデックスを保存するよりもはるかに安全であることに注意してください。
ここで説明した chunk() 関数は、ループのパフォーマンスを最適化するための開始点にすぎません。必要に応じて、さらに機能を追加するために改良を続けることができます。たとえば、配列内のすべてのオブジェクトが処理された後、関数コールバックを追加できます。この方法で関数を変更するかどうかに関係なく、これは配列処理のパフォーマンスを最適化し、スクリプトが制御不能になっているという警告を回避するのに役立つ単なる JavaScript コード開発パターンです。
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。