2010-12-07 9 views
1

XMLファイルの配列をロードして配列に格納します。非同期XMLHttpRequestを使用してXMLファイルの配列をロードする

コード例:

var src = [ "a", "b", "c", "d" ]; 
var dest = {}; 
for (var i in src) { 
    var req = new XMLHttpRequest(); 
    req.open("GET", src[i], true); 
    req.onreadystatechange = function(aEvt) { 
     if (req.readyState == 4) { 
      if (req.status == 200) { 
       dump(i + "\n"); 
       dest[i] = req.responseXML; 
      } 
     } 
    } 
    req.send(null); 
} 

はしかし、ダンプ結果は常に

です210

コールバックで参照されるiが常に外部iであることを示しているため、XMLファイルを正しく保存できません。

この問題を解決するにはどうすればよいですか?私たちは約50のXMLファイルを読み込み、ロードすることはできません。

ありがとうございます。

答えて

5
  1. 配列をループオーバーするのにfor..inを使用しないでください。通常のforループを使用してください。
  2. ループ内で関数を作成する典型的な間違いをします。 JavaScriptにはブロックスコープはなく、関数スコープのみがあります。したがって、iは、作成した関数が実行されたときにループした配列の最後の要素を常に参照します。彼らはすべてと同じiを参照しています。これを解決するには、関数を返す直ちに実行する関数を使用します(したがって、値はiです)。
  3. reqへの参照を取得する必要があります。それ以外の場合は、常に最後に生成されたXMLHttpRequestを参照します(iと同じ理由)。

だから、一つの解決策は、次のようになります。

@Spinyノーマンのソリューションは、より読みやすいかもしれません
var src = [ "a", "b", "c", "d" ]; 
var dest = {}; 
for (var i = src.length;i--;) { 
    var req = new XMLHttpRequest(); 
    req.open("GET", xmlfile, true); 
    req.onreadystatechange = (function(i, req) { 
     return function(aEvt) { 
      if (req.readyState == 4) { 
       if (req.status == 200) { 
        dump(i + "\n"); 
        dest[i] = req.responseXML; 
       } 
      } 
     }; 
    }(i, req)); // capturing the current value/reference of i and req 
    req.send(null); 
} 

;)

+1

+1 for.inを使用していないためです。私は私の答えを修正しています:) –

+0

実際のコードでは、私はオブジェクトでループしています、ありがとう! –

+0

EXCELLENT ....しかし、私のforループが何回も繰り返されて(例えば20回)、それぞれがネットワークリクエストである場合、どうすれば実際に他のスレッドをすべて削除/閉じることができますか? –

3

あなたはこのような何か行うことができます:ところで

var src = [ "a", "b", "c", "d" ]; 
var dest = {}; 
var loadXml = function(i) { 
    var req = new XMLHttpRequest(); 
    req.open("GET", xmlfile, true); 
    req.onreadystatechange = function(aEvt) { 
     if (req.readyState == 4) { 
      if (req.status == 200) { 
       dump(i + "\n"); 
       dest[i] = req.responseXML; 
      } 
     } 
    } 
    req.send(null); 
}; 

for (var x = 0; x < src.length; x++) { 
    loadXml(x); 
} 

を、あなたが常に同じXMLFILEをロードしているようだが、私は、これはあなたの実際のコードが異なっていると確信している。

+0

はどうもありがとうございましたが、それはより多くを持っているので、私は正しいとフェリックスクリングのソリューションをマークしています説明。 –

+0

スタックオーバーフローの最善の答えの一つ......私たちはすべてのリクエストを取り消すことができる方法はありますか?つまり、forループが100回実行される場合、何らかの方法がありますUIのボタン)はまだ実行中の他のリクエストを停止/中止します...ありがとう –

関連する問題