0

一連のXMLドキュメントにアクセスする必要があり、各リクエストを動的に生成するforループを使用してアクセスしようとしています。

for (i=0;i<routes.length;i++) {
routeRequestURL = "http://webservices.nextbus.com/service/publicXMLFeed?command=routeConfig&a=sf-muni&r=" + routes[i].name + "&terse";
routeRequest.open("GET", routeRequestURL);
routeRequest.send();
routeResponse = routeRequest.responseXML;
route = routeResponse.getElementsByTagName("route")[0];
for (var j = 0; j < route.childNodes.length; j++) {
    if (route.childNodes[j].tagName == "stop") {
        routes[i].stops.push(new Stop(route.childNodes[j].getAttribute("tag"), route.childNodes[j].getAttribute("lat"), route.childNodes[j].getAttribute("lon")));
    }
  }
}

routesrouteオブジェクトの配列であり、3つの変数、、、、nameおよびlabelがありstops、それ自体がstopオブジェクトの配列です。

Chromeのjavascriptコンソールでコードを試してみましたが、外側のループ内の各行を。で実行すると機能しましたroutes[0]。コンソールでループを実行しようとすると、次のエラーメッセージが表示されましたTypeError: Cannot call method 'getElementsByTagName' of null

コードの各行をroutes[0]エラーなしで実行する場合routeResponse、forループの最初の反復中にnullが発生するのはなぜですか?どこかでクロージャエラーがありませんか?

編集:私はコールバックを含めようとしましたreadystatechangeが、javascriptに慣れていないため、それを行う方法を完全に理解することができませんでした。私は試した:

for (i=0;i<routes.length;i++) {
routeRequestURL = "http://webservices.nextbus.com/service/publicXMLFeed?command=routeConfig&a=sf-muni&r=" + routes[i].name + "&terse";
routeRequest.open("GET", routeRequestURL);
routeRequest.onreadystatechange = function() {
    routeResponse = routeRequest.responseXML;
    route = routeResponse.getElementsByTagName("route")[0];
    for (var j = 0; j < route.childNodes.length; j++) {
        if (route.childNodes[j].tagName == "stop") {
            routes[i].stops.push(new Stop(route.childNodes[j].getAttribute("tag"), route.childNodes[j].getAttribute("lat"), route.childNodes[j].getAttribute("lon")));
        }
      }
    }
routeRequest.send();
}

うまくいきませんでした。

4

1 に答える 1

1

2つのこと:

  1. 追加したコールバック内でreadystatechange、応答の読み込みが完了したかどうかを確認する必要があります
  2. コールバックはクロージャを導入します。これにより、への参照に問題が発生しますi

次のコードは、両方の問題に対処する必要があります。

routeRequest.onreadystatechange = (function(i) { return function() {
    if(routeRequest.readyState == 4 && routeRequest.status == 200) {
        routeResponse = routeRequest.responseXML;
        route = routeResponse.getElementsByTagName("route")[0];
        for (var j = 0; j < route.childNodes.length; j++) {
            if (route.childNodes[j].tagName == "stop") {
                routes[i].stops.push(new Stop(route.childNodes[j].getAttribute("tag"), route.childNodes[j].getAttribute("lat"), route.childNodes[j].getAttribute("lon")));
            }
        }
     }
}})(i);
于 2012-10-03T18:35:32.140 に答える