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")));
    }
  }
}

routes是一个route对象数组,它具有三个变量:namelabelstops,它本身就是一个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

两件事情:

  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 回答