2010-12-07 4 views
0

をループされていません...jqueryの.each()は、代替がうまくいけば、私は何かが欠けていることだし、これは簡単です適切

私はURLのリストをループページを持って、Ajaxが(とそれらに呼び出しを行いますjquery)は、返されたHTMLからデータを取得し、テーブルに表示します。これらの呼び出しは正常に動作します。このデータをリアルタイムで取得してから、ChromeやIEのようなブラウザは、この重い処理中にしばらく時間がかかります(おそらくリストをループしてデータを返し、表示するなど)定期的に「ページが応答しない」というメッセージが表示され、IEはハングアップしているように見えますが、突然の結果が画面に表示されます。

これを解決するために、私はjQueryの.each()関数を最適化する方法を研究し、slowEachというカスタム・プラグインを発見基本的に各ループ反復の後、小さなタイムアウトを挿入(LINK) - ブラウザが取得するようにクライアントが応答しないとは考えません。 .eachの代わりにslowEachプラグインを呼び出すようにコードを更新しました。すべて正常に動作します。最初の反復後、プラグインはコールバック関数の最後まで実際に余分なコードを実行し、突然ループに戻り、残りの反復を正しく続行したいと考えています。

なぜこのようなことが起きているのか、私は苦労しています。ここで

は私のコードは、(parseXmlは、いくつかのXMLデータを処理するだけで、コールバック関数である)である:ここでは

function parseXml(x) 
{ 
    var $rowArray = $(x).find("[nodeName=z:row]"); 

    $rowArray.slowEach(250, function(index) { 
    // ... processing each returned row 
    }); 
// ... extra processing after the loop is completed. Show data on the screen. 
}; 

はslowEachプラグインです:

$.slowEach = function(array, interval, callback) { 
     if(! array.length) return; 
     var i = 0; 
     next(); 
     function next() { 
      if(callback.call(array[i], i, array[i]) !== false) 
       if(++i < array.length) 
        setTimeout(next, interval); 
     } 
    }; 

    $.fn.slowEach = function(interval, callback) { 
     $.slowEach(this, interval, callback); 
}; 

このコードは、何らかの形で「余分になりますループの最初の反復でのみ、私のコードの「処理中」の部分を処理します。非常に奇妙な。おそらくコードがこれをやっている理由を理解する助けとなるかもしれません。より多くの情報が必要な場合は教えてください!ありがとう。

答えて

1

.slowEachsetTimoutを使用すると、他のすべてのページ処理が完了するまで、その関数の機能(each関数の内容)が本質的に延期されます。したがって、呼び出された後のコードを含めて、slowEach呼び出しの外のコードがすべて実行されます。あなたがする必要があるのは、すべてのアイテムが処理された後に.sloweach関数に別の関数を追加して呼び出すことで、// ... extra processing ...コードをそこに置くことです。

未テストコードが、これは働くか、少なくともあなたは正しい方向に軌道に乗る必要があります。

function parseXml(x) 
{ 
    var $rowArray = $(x).find("[nodeName=z:row]"); 

    $rowArray.slowEach(250, function(index) { 
     // ... processing each returned row 
    }, function() { 
     // ... extra processing after the loop is completed. 
     // Show data on the screen. 
    }); 
}; 

プラグインを変更:

$.slowEach = function(array, interval, callback, onCompletion) { 
     if(! array.length) return; 
     var i = 0; 
     next(); 
     function next() { 
      if(callback.call(array[i], i, array[i]) !== false) 
       if(++i < array.length) 
        setTimeout(next, interval); 
       else 
        setTimeout(onCompletion, interval); 
     } 
    }; 

    $.fn.slowEach = function(interval, callback, onCompletion ) { 
     $.slowEach(this, interval, callback, onCompletion ); 
}; 
+0

すごいです!これは完璧に機能しました!最初の実行時に実行されるコード。 setTimeoutを調べるのは間違いなく犯人でした。私はもう少しそれを読み返す必要があります。ありがとう。 – tresstylez

+0

@tresstylez、喜んで助けてください。ここには、JavaScriptのタイミングに関する優れたリソースがあります:http://ejohn.org/blog/how-javascript-timers-work/ – jball

関連する問題