rails + jquery调用javascript函数,返回的值是undefined

时间:2012-07-03 05:34:51

标签: jquery ruby-on-rails ajax

我的生活无法弄清楚这一点。我知道这是ajax进行调用的异步方式的一些问题,但仍然无法确定问题。我有这个:

$(document).ready(function() {
  $('#address').blur(function() {
    console.log("now processing address");
    var add = $("#address").val();
    console.log("address is: " + add);
    var refAdd = processAddress(add);
    console.log("refined addres is: " + refAdd);
  }); 
});

然后我有了我正在调用的processAddress函数(感谢SO上的另一篇文章)。问题是上面的最后一个语句将refAdd返回为undefined。这是为什么??

function processAddress(address){
  var geocoder = new google.maps.Geocoder();
  if (geocoder) {
    geocoder.geocode({ 'address': address }, function (results, status) {
      if (status == google.maps.GeocoderStatus.OK) {
        //console.log(results[0].geometry.location);
        console.log(results[0].formatted_address);
        console.log("latitude is: " + results[0].geometry.location_type);
      }
      else {
        console.log("Geocoding failed: " + status);
        //formatted_address = "Geocoding failed: " + status;
        formatted_address = "failed"
      }
    });
  } 
}

很明显是一个异步问题,我可以按输出打印的顺序看到; refAdd应该打印到最后但不是。

now processing address
address is: 415 N Mathilda Ave, Sunnyvale
refined addres is: undefined
415 N. Mathilda Ave, Sunnyvale, CA, USA
latitude is: ROOFTOP

1 个答案:

答案 0 :(得分:0)

你是对的,问题是因为函数是异步的(我怎么知道?因为正如你所说:logs是异步写的 geocoder.geocode使用的打回来)。你必须使用回调,如下所示:

$(document).ready(function() {
  $('#address').blur(function() {
    console.log("now processing address");
    var add = $("#address").val();
    console.log("address is: " + add);

    // adding callback to call.
    processAddress(add, function(refAdd) {
      console.log("refined addres is: " + refAdd);
    });
  }); 
});

并在函数中:

function processAddress(address, callback){ // <---- note the callback arg
  var geocoder = new google.maps.Geocoder();
  if (geocoder) {
    geocoder.geocode({ 'address': address }, function (results, status) {
      if (status == google.maps.GeocoderStatus.OK) {
        //console.log(results[0].geometry.location);
        console.log(results[0].formatted_address);
        console.log("latitude is: " + results[0].geometry.location_type);
        callback('TEST'); // <---- pass here the value you need
      }
      else {
        console.log("Geocoding failed: " + status);
        //formatted_address = "Geocoding failed: " + status;
        formatted_address = "failed"
        callback('TEST'); // <---- pass here the value you need
      }
    });
  } else {
    callback(); // <---- pass here for example error if you need
  }
};

我不知道这个geocoder的东西,所以你需要根据自己的需要进行自定义。