2012-04-14 13 views
24

私はいくつかのウェブサイトを開発しましたが、私はいつも同じポイントをつまずきます:複数のajax呼び出し。私はすべてのコンテンツが非同期にロードされるメインページを持っています。ページがロードされると、4つの独立した呼び出しがあり、ページを領域(上、左、右、下)で「描画」し、ロードされている間、典型的なajaxスピンをユーザーに示します。したがって、リクエストがブラウザによって受信されると、私はコールバックを実行し、異なるエリアが異なる時間に描画しています。実際には、サーバの回答が時々混ざり合っている、つまり、上の答えが左に、またはその逆が左に描かれているということです。複数のajaxが同時に呼び出す

各リクエストでタイムスタンプを作成して、ブラウザとサーバーにそれぞれのリクエストが異なることを示すようないくつかのソリューションを試しました。

また、サーバーのキャッシュのいくつかのパラメータを設定しようとしました。

1のコールバックでrequest2を含むされています働いている唯一の方法は、など

誰もがそれを行うための適切な方法を知っているか、これまでこの問題を殴られました?私は連鎖した要求をしたくありません。ここで

おかげ

は、私が何を意味するかの例です:

$(document).ready(function() { 

$.get('/activity',Common.genSafeId(),function(data){$('#stream').html(data);$("#load_activity").addClass("empty");}); 
$.get('/messages',Common.genSafeId(),function(data){$('#message').html(data);$("#load_messages").addClass("empty");}); 
$.get('/deals',Common.genSafeId(),function(data){$('#new_deals_container').html(data);$("#load_deal").addClass("empty");}); 
$.get('/tasks',Common.genSafeId(),function(data){$('#task_frames').html(data);$("#load_task").addClass("empty");});}); 

とHTMLは4つのコンテナの異なるIDを持つ各1との簡単なJSPです。

+3

答えは間違った場所に描かれていますが、どういう意味ですか?正しく構築されたAjax呼び出しは、レイアウトの非常に特定の場所にあるHTMLの非常に特定の部分を更新します。問題を示す簡単なコードを投稿してください。 –

+0

あなたのページに$( '#container')のような内容を追加していますか?append()? – jimw

+0

はい、投稿を更新しました。コンテンツはDOMに追加されますが、要求が不適切なIDでコンテンツを描画することがあります。私は奇妙なことを知っている、その理由のために私は通常、チェーンの要求を行う。両方の答えに感謝します。 –

答えて

-5

各AJAX呼び出しごとに異なるコールバックがあることを確認してください。すべての4つの関数で同じ機能を使用しようとしているように聞こえるため、順序が間違ってコールされる(サーバー側の時間が異なるため) 、彼らは間違った場所でレンダリングしています。すべてのコールバックに同じ関数を使用することを主張するなら、コールバックがどこにレンダリングするかを知るために何かをペイロードに入れなければなりません。

+2

個別の関数はこれに近づく方法ではありません。クロージャーで値を保持して、応答をどこに送るべきかを判断するのは簡単です。 –

+0

True Beetroot-Beetroot、しかし私は彼がjQueryを使用していないと確信しています。 –

+3

閉鎖を行うにはjQueryが必要だと誰が言いますか? –

39

閉鎖

Closuresは、最初は少し心を吹いています。これらはjavaScriptやその他の最新のコンピューティング言語の機能です。

クロージャは、1つまたは複数の外部変数(つまり、外部関数内の変数)にアクセスする必要がある内部関数(通常は匿名イベントハンドラまたは名前付きメソッド)を持つ関数の実行インスタンスによって形成されます。内部関数の外側にある)。思いがけないことは、内部関数が実行するときに外部関数が完了して戻っても、内部関数が外部変数へのアクセスを保持していることです。

さらに、クロージャによってトラップされた変数は、内部関数に対してのみアクセス可能であり、クロージャを存在させるさらなるアウト環境にはアクセスできません。この機能により、例えば、言語キーワード "Public"と "Private"がなくても、プライベートメンバーとパブリックメンバーを持つクラスのような構造を作成することができます。

内部関数の外部変数を使用することで、JavaScriptの「ガーベジコレクション」を抑制し、完了後にいくつかの不確定点で外部関数の環境を破壊する可能性があります。

良い、整然としたjavaScriptプログラミングのクロージャの重要性は、過度に強調することはできません。機能getData()フォーム以下のコードで

、各呼び出しでは、匿名のAjaxのレスポンスハンドラに利用できるまま id1id2(および url)を捕捉するクロージャ、($に.getの第三引数)。

$(document).ready(function() { 

    function getData(url, id1, id2) { 
     $.get(url, Common.genSafeId(), function(data) { 
      $(id1).html(data); 
      $(id2).addClass("empty"); 
     }); 
    } 

    getData('/activity', '#stream', '#load_activity'); 
    getData('/messages', '#message', '#load_messages'); 
    getData('/deals', '#new_deals_container', '#load_deal'); 
    getData('/tasks', '#task_frames', '#load_task'); 

}); 

したがって、むしろ、4つの別々のハンドラを書くよりも、我々はクロージャを形成し、同じ機能、getData()、4回を呼び出すために、言語の能力を活用します。各呼び出しで、getData()は新しいクロージャを作成します。このクロージャは、 DOM要素にアドレスするために$ .getの応答ハンドラ(サーバーが応答すると非同期に呼び出されます)を許可します。

+3

私はこの答えから多くを学んだが、問題の元のコードに何が間違っていたかを理解するためにしばらく時間をとった。それは変数 "データ"が実際にはそれぞれの呼び出しに対して同じオブジェクト/インスタンスなので、内部関数(クロージャ)によっても再利用されるからですか?私は半分の4つのオブジェクトを作成することをJavaScriptランタイムが知っていると半分は予想していたと思います。私が扱っている他のほとんどの言語では、そのような騒ぎのレベルに対処する必要はありません。 – eselk

+0

@eselk、この9ヶ月後にもう一度見て、私はどのように/なぜ質問のコードは物事を混乱させることができたか分からない。私は質問に答え始めた後に追加されているはずだと思います。OPの独自の解決策であるかどうか、症状を説明したコードではないかと思います。確かに、 '$ .get()'の4つの独立した関数は不要です。私の 'getData()'関数は問題を単純化します。一旦あなたの心の丸いクロージャーを持っていれば、彼らはかなりシンプルです - そして正式な定義よりもはるかに簡単です。 –

+0

@ Beetroot-Beetrootページの読み込み時に同時に12回のajax呼び出しを行う必要があります。ある応答が別の応答にコピーされているようです。これは同時呼び出し数のブラウザの制限によるものですか? –

関連する問題