2011-08-25 8 views
14

Mi pregunta es acerca de Javascript. Tengo una función de devolución de llamada que recibe un objeto de posición en una devolución de llamada exitosa.Javascript asignando el valor de retorno de una función de devolución de llamada a la variable global

El problema es que cuando intento establecer las propiedades del objeto Position en una variable global en una devolución de llamada exitosa, simplemente no me deja hacerlo y lo global simplemente permanece indefinido. Como solución alternativa a eso, en lugar de establecer directamente las propiedades del objeto como variables globales, intento devolverlo a través de la función de devolución de llamada, pero no encontré la manera de establecer el valor devuelto variable.

Aquí está el código simplificado.

var x; 

navigator.geolocation.getCurrentPosition(onSuccess, onError); 

//on Successful callback receives a Position Object 
function onSuccess(position) { 
    var coords = position.coords; 
    x=coords;  // Setting directly to an object does not work x still remains undefined after succesful callback    
return coord; // Trying to set this to a global object 

} 

// onError Callback receives a PositionError object 
// 
function onError(error) { 
    alert('code: ' + error.code + '\n' + 
      'message: ' + error.message + '\n'); 
} 

Respuesta

15

No se puede devolver un valor de la devolución de llamada (en este caso). Eso significaría que dentro de getCurrentPosition, el valor de retorno de la devolución de llamada debe asignarse en algún lugar.

La asignación a una variable global funciona, pero en el momento de acceder a esa variable, aún no se le asignó el nuevo valor. P.ej.

// x is assigned in `onSuccess` 
var x; 
navigator.geolocation.getCurrentPosition(onSuccess, onError); 
alert(x); // will be undefined, the response is not processed yet 

Piense en esto: getCurrentPosition es, probablemente, haciendo una petición Ajax para obtener la posición. Tal solicitud toma (a) el tiempo (un par de milisegundos) y debido a eso (b) es asincrónico, lo que significa que JavaScript no espera hasta que se reciba la respuesta. Su código es manera más rápido. onSuccess no se llamó aún cuando alerta x.

Única solución:

todo el código que tiene para acceder a la condición de estar en o llamados desde la devolución de llamada.

+0

realmente buen punto, mi respuesta es un descuido estúpido de mi parte. el código no es lineal, por lo que tendrá que hacer lo que quiera con los coords en la devolución de llamada, para asegurarse de que el valor ha sido vinculado – WickyNilliams

+0

En realidad tiene razón. La función getCurrentPosition está tratando de obtener la geolocalización que es asincrónica es por eso que cuando intento acceder desde la variable global, probablemente no esté configurado y vuelva a estar indefinido. ¿No hay forma de asignarle a la variable el valor devuelto después de que la función asíncrona haya terminado con su trabajo? –

+0

@Torukojin: No, ¿a dónde debería devolver el valor? Como se dijo, el código se ejecuta de forma asíncrona. Es por eso que el valor pasa como un parámetro de la función de devolución de llamada para que pueda usarlo y hacer lo que quiera con él. Si fuera posible 'devolver 'el valor, entonces' getCurrentPosition' lo haría. Pero no lo es, por lo tanto, ha proporcionado una devolución de llamada. Tal vez encuentre [este artículo] (http://felix-kling.de/blog/2011/01/14/how-to-return-data-from-an-ajax-call/) útil para comprender el problema (pero no soy tan bueno escribiendo;)) –

0

¿Ha intentado configurarlo a través del objeto global window?

//on Successful callback receives a Position Object 
function onSuccess(position) { 
    var coords = position.coords; 
    window.x=coords;  // Setting directly to an object does not work x still remains undefined after succesful callback    
return coord; // Trying to set this to a global object 

} 

Además, dado que devuelve las coordenadas del controlador de éxito, ¿no hay otra forma de obtener este valor?

0

poner un console.log(x); justo después x=cords para comprobar el valor (funciona en Chrome y FF con FireBug)

hacer eso también justo después de la llamada de onSuccess.

Asimismo, no hay que olvidar que existe un código asíncrono de JS (si se utiliza AJAX para obtener la posición), tal vez lo que no recibe la respuesta cuando se registre el valor de x

+0

En realidad ya lo estoy haciendo, aunque no mencioné :) –

1

Según lo descrito por Felix King, no puede devolver un valor de una devolución de llamada y en su variante de variable global, la variable no se establecerá hasta después de que la solicitud AJAX se complete y llame a la devolución de llamada (¡de ahí su nombre!).

Usando una variable global puede resolver su problema si tiene algún tipo de bucle de procesamiento, puede agregar este código a ese bucle para hacer lo que sea necesario cada vez que cambie la coord.

if (coord) // global variable has a new value 
    // process it 
    alert('code: ' + error.code + '\n' + 
      'message: ' + error.message + '\n'); 
    // then clear it 
    coord = null; 
    } 
0

se puede implementar un método de ayuda al igual que fluye:

var LocationHelper = function() {}; 

LocationHelper.prototype.getLocation = function(callback) { 

    navigator.geolocation.getCurrentPosition(onSuccess, onError); 

    function onSuccess(pos) { 
     callback({ 
      pos: pos 
     }); 
    } 

    function onError(message) { 
     callback({ 
      message: message 
     }); 
    } 

    }; 
Cuestiones relacionadas