【问题标题】:Iterating through an array while performing a request for each entry在对每个条目执行请求时遍历数组
【发布时间】:2008-12-30 18:01:15
【问题描述】:

这是我的问题。我有一个数组,其中包含我需要查找天气的城市名称。所以我正在遍历每个城市并执行 AJAX 请求来检索天气。

var LOCATION = 'http://www.google.com/ig/api?weather=';

$( document ).ready( function() {
    for( var cityIdx = 0; cityIdx < cities.length; cityIdx++ ) {
        $.ajax({
            type: 'GET',
            url: LOCATION + cities[ cityIdx ],
            dataType: 'xml',
            success: function( xml ) {
                if( $( xml ).find( 'problem_cause' ) != 0 ) {
                    // Do what I want with the data returned
                    var weather = $( xml ).find( 'temp_c' ).attr( 'data' );
                }
            }
        });
    }
});

我遇到的问题是在成功功能中,我无法访问城市名称(通过城市 [cityIdx])。我在 for 循环和成功函数中插入了一个 alert(),看起来循环执行了 cities.length 次,然后我得到了成功函数警报。我的目标是简单地遍历每个城市以获取天气并将其与相关城市名称一起显示在我的页面上。

另外,您建议我应该怎么做才能将内容与演示分开?

谢谢。 :)

【问题讨论】:

    标签: javascript jquery ajax


    【解决方案1】:

    我怀疑您的问题与http://ejohn.org/apps/learn/ 的示例类似。索引变量 cityIdx 在处理 for 循环时在您创建的闭包中更新,因此当您的函数成功运行时,cityIdx 将指向数组中的最后一个元素。解决方案是使用评估的匿名函数来创建一个独立的上下文,其中索引值不会被更新。

    //...
    success: (function(cities, idx) {
        return function( xml ) {
          if( $( xml ).find( 'problem_cause' ) != 0 ) {
            // Do what I want with the data returned
            // use cities[idx]
            var weather = $( xml ).find( 'temp_c' ).attr( 'data' );
          }
        };
      })(cities, cityIdx)
    //...
    

    【讨论】:

      【解决方案2】:

      由于 Javascript 使用函数进行闭包,我发现对我来说最简单的方法是将 for 循环的内容包装在一个内联函数中,该函数将当前城市名称复制到它始终可以访问的变量中。

      $(document).ready(function() {
          for (var cityIdx = 0; cityIdx < cities.length; cityIdx++) {
              new function() {
                  var currentCity = cities[cityIdx];
                  $.ajax({
                      type: 'GET',
                      url: LOCATION + currentCity,
                      dataType: 'xml',
                      success: function(xml) {
                          alert(currentCity);
                          if ($(xml).find('problem_cause') != 0) {
                              // Do what I want with the data returned
                              var weather = $(xml).find('temp_c').attr('data');
                          }
                      }
                  });
              }(); // the "();" calls the function we just created inline
          }
      });
      

      【讨论】:

      • 我认为您应该删除“新”
      • 尝试删除“new”会导致语法错误。我相信这是因为您正在创建该函数的实例以供立即使用,而不是将其传递给 .ready() 函数。我认为 .ready() 函数将传递的函数对象放入队列中,以便稍后实例化和执行。
      【解决方案3】:

      为什么不使用 jQuery 来遍历你的数组呢?使用jQuery的each函数:

          var LOCATION = 'http://www.google.com/ig/api?weather=';
      
      $( document ).ready( function() {
      
          $.each(cities, function()  {
          //assign the current city name to a variable
              var city = this;
              $.ajax({
                      type: 'GET',
                      url: LOCATION + city,
                      dataType: 'xml',
                      success: function( xml ) {
                          if( $( xml ).find( 'problem_cause' ) != 0 ) {
                              alert(city);
                                  // Do what I want with the data returned
                              var weather = $( xml ).find( 'temp_c' ).attr( 'data' ); 
                          }
                      }
              });
          });
      });
      

      成功功能中的警报显示正确的城市。

      【讨论】:

      • 谢谢。我已经更新了我的函数以使用 for each。 :)
      【解决方案4】:

      最简单的做法是让您的 AJAX 请求返回城市名称。

      【讨论】:

        【解决方案5】:

        出于各种原因,我会尝试将成功函数提取到单独定义的函数中,然后在包含城市名称的 ajax 调用中为其创建一个闭包。所以首先,一个单独的成功处理程序:

        function city_success(xml, name) {
          // your success handling code here
        }
        

        然后在ajax调用中修改成功绑定:

        success: function (xml) { city_success(xml, cities[ cityIdx ]); },
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-11-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-12-07
          相关资源
          最近更新 更多