【问题标题】:For loop generating multiple XML requests in JavascriptFor循环在Javascript中生成多个XML请求
【发布时间】:2012-09-24 17:03:15
【问题描述】:

我需要访问一系列 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] 运行每一行代码都不会产生错误,那么为什么在for 循环的第一次迭代中routeResponse 为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();
}

没用。

【问题讨论】:

  • 您缺少readystatechange 回调,因为请求是异步的。
  • 我对 javascript 还是很陌生...如何包含该回调?

标签: javascript xml for-loop xml-parsing xmlhttprequest


【解决方案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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-25
    • 2017-08-08
    • 2016-11-13
    • 2021-02-09
    • 1970-01-01
    • 1970-01-01
    • 2021-04-11
    • 1970-01-01
    相关资源
    最近更新 更多