Let's examine your code:
function Publication(){
navigator.geolocation.getCurrentPosition(showPosition);
function showPosition(position){
var geocoder = new google.maps.Geocoder();
lat=position.coords.latitude;
lon=position.coords.longitude;
latlonmarker= new google.maps.LatLng(lat, lon);
geocoder.geocode({ 'latLng': latlonmarker },geocoderact);
}
return Ciudad1;
}
It is noted that the call to your function geocoderact
is a callback ; that is, it is asynchronous and does not run in the order in which you believe; your Publication function returns City1 before that your geocoderact
function modifies it.
The exact behavior of your code is:
... several actions ...
we place the call to geocoderact
in the pending event queue.
... other actions ...
we return City1, which has not yet been modified.
Resto de código a ejecutar hasta que lleguemos al return final ...
When you reach the last return
and finish the sequential code execution completely, then ...
The browser processes pending events.
One of those events is your call to geocoderact()
geocoderact()
changes the value of your variable City1.
The new value is now available.
The browser continues processing other pending events.
one of those other pending events is your new button click, where you access Ciudad1
which, now, has already been modified.
In fact, if you look at the results your page offers you, every time you press the button it will show you the result of the previous click .
In the Mozilla Developer Network they explain it in detail:
link
EDITO
callbacks ARE INEVITABLE in Javascript
, due to their own event-oriented nature; use any code that works with the network or with user events; the expression callbacks hell (hell of callbacks ) refers to the difficulty of programming in this way, which makes it difficult to know exactly where we are, how we got here , and where will we go next.
In this particular case, the no changes are to eliminate the callbacks , which is impossible since they are used by the geocoder
object and we do not know anything about it.
The solution is to convert our functions into callback functions, that is, change our programming mode from linear to event-oriented :
For this, we have the function setTimeout( FUNCTION, TIME )
. Simply using setTimeout( FunciónALlamar, 0 )
creates a new event that is placed at the end of the queue, and the browser will process it when it can.
The previous code could be modified in the following way:
function Publication(){
. . .
latlonmarker= new google.maps.LatLng(lat, lon);
geocoder.geocode({ 'latLng': latlonmarker },geocoderact);
}
}
We eliminate the return
, which is useless.
function geocoderact(results, status){
if (status == google.maps.GeocoderStatus.OK) {
if (results[0]) {
Ciudad= results[0].address_components[4].long_name;
Ciudad1 = Ciudad;
setTimeout( ShowResult, 0 ); // Llamamos a nuestro propio callback.
} else {
error('Google no retorno resultado alguno.');
}
} else {
error("Geocoding fallo debido a : " + status);
}
}
If all went well, we called our own callback , to show us the result.
function ShowResult( ) {
alert( Ciudad1 );
}
We show the result, or do anything else.
function Public( ) {
setTimeout( Publication, 0 ); // Que se ejecute cuando el navegador pueda.
$.ajax( {
url: "Public.html",
. . .
We no longer need the variables.