2012-12-24 23 views
9

私の背景は、C++や.NETプログラミングなどの従来のコンパイル済みオブジェクト指向言語で書かれており、新しいプロジェクト用のJavaScriptに慣れています。私はAJAXに手を貸していて、オブジェクトがブラウザによってどのように管理されているのか混乱していました。Javascriptでxmlhttprequestオブジェクトを作成、マージ、破棄する方法

  1. ボタンテキストを持つ1更新TextArea1: -

    [編集]#2]アクティブコンテンツスクリプトの変更

    私は<textarea>XMLHttpRequestオブジェクトを使用して、各アップデート三つのボタンとの練習ページを持っていますコンテンツfrom slowtime.php

  2. ボタン2は、テキストコンテンツをslowtime.phpから更新します。テキストの内容と
  3. ボタン3つの更新TextArea3 fasttime.php

slowtime.phpfasttime.phpからが、2つのタイムスタンプで、テキスト/ HTMLページを返す簡単なスクリプトです:1しばらくしてからページが読み込まれます。

各ボタンは、一度に1つずつクリックすると正しく動作します。最初の要求が完了する前にボタン2をクリックしてからボタン3をクリックすると、アップデートは引き続き正常に機能します。

最初のリクエストが完了する前にボタン1をクリックしてからボタン2をクリックすると、TextArea1とTextArea2が正しい値を受け取ります。ただし、onreadystatechangeイベントコールは同時に発生します。つまり、最初に応答し、2番目のイベントが到着したときにのみ処理されます。

サンプルコード

サイト

<!DOCTYPE html> 
<html> 
<head> 
<script> 
function loadXMLDoc(url,target) 
{ 
var xmlhttp; 
xmlhttp=new XMLHttpRequest(); 

xmlhttp.onreadystatechange=function() 
    { 
    if (xmlhttp.readyState==4 && xmlhttp.status==200) 
    { 
    document.getElementById(target).value=xmlhttp.responseText; 
    } 
    } 
xmlhttp.open("POST",url,true); 
xmlhttp.send(); 
} 
</script> 
</head> 

<body> 
<form> 

<input type="button" value="Button 1" onClick="loadXMLDoc('slowtime.php','TextArea1')"/> 
<input type="button" value="Button 2" onClick="loadXMLDoc('slowtime.php','TextArea2')"/> 
<input type="button" value="Button 3" onClick="loadXMLDoc('fasttime.php','TextArea3')"/> 

<div><textarea id="TextArea1"></textarea></div> 
<div><textarea id="TextArea2"></textarea></div> 
<div><textarea id="TextArea3"></textarea></div> 

</form> 
</body> 
</html> 

PHPコード(slowtime.php

<?php 
    echo date('h:i:s') . "\n"; 
    sleep(5); 
    echo date('h:i:s') . "\n"; 
?> 

質問[改訂]

ブラウザはどのようにXMLHttpRequestオブジェクトを管理していますか?ボタン2と3を押すと、押すたびに新しいオブジェクトがインスタンス化され、それぞれに独立したイベントハンドラがあります。オブジェクトが初期関数呼び出しを過ぎても(それらのイベントハンドラが生き残っているので)、メモリから消去されたとき/破壊されたとき?

XMLHttpRequestsが別々のオブジェクトである場合、同じURLに2番目のリクエストを送信すると、最初のリクエストの応答タイミングにどのように影響しますか?これはサーバー側の問題でしょうか?

+0

あなたの 'xmlhttp.onreadystatechange'関数で' xmlhttp.responseText'の代わりに 'this.responseText'を使うべきでしょうか? –

+1

@ JoshuaD.Boydこれは、 'xmlhttp'変数が' loadXMLDoc'の内部のローカルスコープにあるので、何もしてはいけません。 – Tyilo

+0

'onreadystatechange'関数で' xmlhttp'へのすべての参照を 'onreadystatechange'関数に変更すると、同じ動作をします。 – nicholas

答えて

2

XMLHttpRequestへのコンテキストは、オブジェクトに対してdeleteが明示的に呼び出されない限り削除されません。この場合:xmlhttp。あなたは本当にそのvarを何とか追跡して、あなたのアプリケーションを痩せてきれいに走らせたいなら、それを掃除するべきです。 JavascriptはもともとはWebページ用に設計されていたので、あなたが自分でそれを防ぐのでなければ、野生のものを動かす傾向があります。

その他の機能でオブジェクトが使用できなくなったり、コールバックが残ったりすると、ブラウザのガベージコレクタがオブジェクトを削除する可能性があります。

同時に起こっているイベントの問題については、自分自身で問題を再現することはできません。あなたのPHP設定に問題があると思っています。あなたのサーバで複数のスクリプトを一度に実行できない可能性はありますか?

はここでわずかな変化のカップルと、私のサーバー上であなたの例である: http://www.seijinohki.net/test.php

+0

別のテストサーバーでコードを送信していただきありがとうございます。 ChromeやSafariでサイトをテストすると、上記のramboと同じ結果が得られます。両方のテキスト領域が同じ値になります。一方、Firefox、IE9、およびSilkではサポートされていません。あなたのページはMaxthonモバイルブラウザではまったく動作しません。 – nicholas

+0

多くの時間が経過しても、これは答えとして受け入れることができます。なぜなら、それはリクエストのコンテキストに直接対応するからです。面白い議論をして、少なくとも現時点では、ウェブ開発/ブラウザ/などはまだスクリプトを実行する方法では一様であることを示しています。 – nicholas

1

これは、ブラウザの問題です。

  • Chrome 23 & 26このように動作します。
  • オペラ12 doesntの
  • IE 9のdoesnt
  • Firefoxの17のdoesnt

あなたは、URLを一意にする場合は、例えばslowtime.php?1slowtime.php?2その後、クロムはもはやこのように動作しません。

btw-私のテストでは、両方のテキストエリアが同じ値(最初のリクエストの値)で更新されます。最初のリクエストが終了すると更新され、2番目のリクエストが終了すると更新されません。そのバグは確かに間違っているためです。 Webサーバーのログを介して、2番目の要求が送信されないことを確認しました。

+0

kokorohakaiのサーバー上のChromeまたはSafariでテストすると、結果は両方のテキスト領域が同じ値を取得し、最初の要求でタイムアウトします。一方、私のテストサーバー(localhost)では、2つの異なる値を取得し、2つ目の値と時間を合わせました。これは、答えが非常に複雑で、実際にはブラウザとサーバーの両方の動作に基づいていると信じています。 – nicholas

+0

@nicholasローカルサーバーのログに2つの要求が示されていますか?それでも、クロムがテストで1つのリクエストを送信したということは、そのバグ(または奇妙な機能)があることを示しています。 – goat