Как получить несколько возвращаемых значений из функции JavaScript - PullRequest
2 голосов
/ 27 августа 2010

У меня есть вызов функции JavaScript для функции changeMapLocation, в которой я хочу вернуть переменные lat и long1.У меня есть некоторые проблемы в коде, чтобы вернуть эти две переменные и оповещения при вызове функции.

var sample = changeMapLocation(state);
alert(sample.lat1);
alert(sample.lat2); 

function changeMapLocation(state) {
   var addressval=state;
   var address;
   var url;
   var googleUrl= "http://maps.google.com/maps/api/geocode/json?";
   var  sensor  = "&sensor=false";

   if(addressval != null && addressval !="" && addressval.length!=0) {

      address = "address="+encodeURIComponent(addressval);

      $.ajax({
        url:googleUrl+address+sensor,
        type:"POST",
        dataType:"json",
        success:function(longlatJson) {
           var jsonObj = JSON.parse(JSON.stringify(longlatJson));
           var lat = jsonObj.results[0].geometry.location.lat;
           var long1 = jsonObj.results[0].geometry.location.lng;
           alert(lat);
           alert(long1);
           //var latlng = new google.maps.LatLng(lat,long1);
           //alert(latlng);
        },
        error:function(){alert("unable to conect to google server");}
      });
   }
   return(lat1:lat,lat2:long1); 
}

Ответы [ 6 ]

3 голосов
/ 27 августа 2010

У вас там большая проблема. Вы вызываете асинхронный метод $.ajax(), где его функция обратного вызова будет вызываться после возврата из функции changeMapLocation(), и поэтому ваша функция не будет работать так, как вы ожидаете. Следуйте комментариям в примере ниже:

function changeMapLocation(state) {
   var lat;
   var long1;
   // Since the $.ajax() method is using the asynchronous XMLHttpRequest, it 
   // will not block execution, and will return immediately after it is called,
   // without waiting for the server to respond.
   $.ajax({
      url: 'url-here',
      type: 'POST',
      success: function(longlatJson) {
         // The code here will be executed only when the server returns
         // a response to the ajax request. This may happen several 
         // milliseconds after $.ajax() is called.
         var jsonObj = JSON.parse(JSON.stringify(longlatJson));
         lat = jsonObj.results[0].geometry.location.lat;
         long1 = jsonObj.results[0].geometry.location.lng;
         // Now lat and long1 are set, but it is too late. Our 
         // changeMapLocation() function will have already returned.
      }
   });
   // This part will be reached before the server responds to the asynchronous
   // request above. Therefore the changeMapLocation() function returns an  
   // object with two properties lat1 and lat2 with an undefined value.
   return {lat1: lat, lat2: long1};
}

Вы должны рассмотреть возможность рефакторинга вашего кода таким образом, чтобы логика обработки ответа ajax находилась в обратном вызове success. Пример:

function changeMapLocation(state) {
   $.ajax({
      url: 'url-here',
      type: 'POST',
      success: function(longlatJson) {
         var jsonObj = JSON.parse(JSON.stringify(longlatJson));
         var lat = jsonObj.results[0].geometry.location.lat;
         var long1 = jsonObj.results[0].geometry.location.lng;

         // Update your map location in here, or call a helper function that
         // can handle it:
         myGoogleMap.setCenter(new google.maps.LatLng(lat, long1));
      }
   });
}

Обратите внимание, что changeMapLocation() больше ничего не возвращает. Он просто изменит местоположение карты самостоятельно, когда сервер ответит на запрос Ajax.


Кроме того, обратите внимание, что ваши переменные lat и long1 были включены в область действия внутренней функции success и недоступны из внешней функции.

2 голосов
/ 27 августа 2010

Оберните их обоих в один объект и верните этот объект:

var result = {
    lat:lat,
    long:long1
}

return result;

Затем в вызове вашей функции:

var result = functionName();
alert("lat: " + result.lat + "\n" + "long: " + result.long);
1 голос
/ 27 августа 2010

Или немного более длинная версия, которая немного более читабельна

function getValues()
{
  var r = {};
  r.lat = 22;
  r.lat2 = 33;

  return r;
};


var x = getValues();
alert(x.lat);
alert(x.lat2);
1 голос
/ 27 августа 2010

Вы можете вернуть только одно значение. Это значение может быть объектом, но в синтаксисе используется {}, а не ().

А асинхронный JavaScript и XML равен Асинхронный . Что касается вызывающей функции, то это огонь и забыть, вы не можете вернуть значение из нее.

Ваш обратный вызов должен завершить задачу, он не может передать данные обратно чему-либо другому, чтобы завершить его.

0 голосов
/ 27 августа 2010

Как отмечалось в других ответах, при асинхронном вызове вы не получите значения сразу после вызова Ajax, так как вызов ajax не был бы завершен. так что вы получаете значения как неопределенные. У вас есть два варианта:

Вариант 1:

Переместите операции, которые вы выполняете с возвращаемыми значениями ajax, в функцию обратного вызова success вызова ajax. См. Ответ Энди или Даниэля Вассалло.

Вариант 2: (асинхронный: ложь)

Вы можете сделать вызов синхронным, установив опцию async: false для функции ajax () . Затем этот метод будет блокироваться до тех пор, пока ответ не будет получен, и после его завершения значения будут инициализированы с помощью Ajax.

со вторым вариантом ваш код будет выглядеть так:

function changeMapLocation(state) { 
//  var addressval = $("#address").val(); 
var addressval=state; 
var address; 
var url; 
var googleUrl= "http://maps.google.com/maps/api/geocode/json?"; 
var  sensor  = "&sensor=false"; 
var lat;
var long1;

if(addressval != null && addressval !="" && addressval.length!=0) { 

    address = "address="+encodeURIComponent(addressval); 

    $.ajax({ 
    url:googleUrl+address+sensor, 
    type:"POST",
    async: false, 
    dataType:"json", 
    success:function(longlatJson) { 

        var jsonObj = JSON.parse(JSON.stringify(longlatJson)); 
        lat = jsonObj.results[0].geometry.location.lat; 
        long1 = jsonObj.results[0].geometry.location.lng; 
        alert(lat); 
        alert(long1); 
        //var latlng = new google.maps.LatLng(lat,long1); 
        //alert(latlng); 

    }, 
    error:function(){alert("unable to conect to google server");} 
    }); 
} 
return {lat1:lat,lat2:long1}; 

}
0 голосов
/ 27 августа 2010

Чтобы вернуть несколько значений, вам нужно создать объект.

return({
   lat1:  lat,
   lat2:  long1
});

Кроме того, этот код также не будет работать, поскольку $.ajax() создает запрос асинхронный , который запускаетпозже, чем ваш return statement.

Так что вам нужно вызвать свой собственный обратный вызов.как

function changeMapLocation(state, cb){
    $.ajax({
         // much data
         success: function(longlatJson) {
             // do a lot of things
             if(typeof cb === 'function')
                cb.apply(null, [lat, long1]);
         }
    });
}

, а затем назвать его как

changeMapLocation("foobar", function(lat, long1){
     alert(lat);
     alert(long1);
});
...