2011-08-25 23 views
14

La mia domanda riguarda Javascript. Ho una funzione di richiamata che riceve un oggetto posizione su un callback riuscito.Javascript che assegna il valore di ritorno di una funzione di callback alla variabile globale

Il problema è che quando provo ad impostare le proprietà dell'oggetto Position su una variabile globale con una callback corretta, non mi lascia fare e il globale rimane indefinito.

Come soluzione alternativa a quella invece di impostare direttamente le proprietà dell'oggetto su variabili globali, sto tentando di restituirlo tramite la funzione di callback ma non sono riuscito a trovare un modo per impostare il valore restituito della funzione di callback su un valore globale variabile.

Ecco il codice semplificato.

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'); 
} 

risposta

15

Non è possibile restituire un valore dalla richiamata (in questo caso). Ciò significherebbe che all'interno di getCurrentPosition, il valore di ritorno dal callback deve essere assegnato da qualche parte.

L'assegnazione a una variabile globale funziona, ma al momento dell'accesso a tale variabile, non è stato ancora assegnato il nuovo valore. Per esempio.

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

Pensateci: getCurrentPosition è probabilmente facendo una richiesta Ajax per ottenere la posizione. Tale richiesta richiede (a) tempo (un paio di millisecondi) e per questo (b) è asincrono, il che significa che JavaScript non attende finché non viene ricevuta la risposta. Il tuo codice è modo più veloce. onSuccess non è stato ancora chiamato quando si avvisa x.

Unica soluzione:

Tutto il codice che deve accedere alla posizione di essere in o chiamato dal callback.

+0

realmente buon punto, la mia risposta è una svista stupido da parte mia. il codice non è lineare quindi è necessario fare tutto ciò che si vuole fare con i coords nella callback, per assicurarsi che il valore sia stato associato – WickyNilliams

+0

In realtà hai ragione. La funzione getCurrentPosition sta cercando di ottenere la geolocalizzazione che è asincrona è per questo che quando provo ad accedervi dalla variabile globale probabilmente non è impostato e restituito indefinito. Non c'è modo di assegnare la variabile per restituire il valore dopo che la funzione asincrona viene eseguita con il suo lavoro? –

+0

@Torukojin: No, dove deve essere restituito il valore? Come detto, il codice funziona in modo asincrono. Ecco perché il valore viene passato come parametro alla funzione di callback in modo che tu possa usarlo e fare quello che vuoi con esso. Se fosse possibile restituire il valore, allora 'getCurrentPosition' lo farebbe. Ma non lo è, quindi hai fornito una richiamata. Forse troverai [questo articolo] (http://felix-kling.de/blog/2011/01/14/how-to-return-data-from-an-ajax-call/) utile per capire il problema (ma non sono così bravo a scrivere;)) –

0

hai provato a impostarlo tramite l'oggetto globale 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 

} 

anche, dal momento che si torna alle coordinate dal gestore successo, non c'è forse un altro modo per ottenere questo valore?

0

mettere un console.log(x); subito dopo x=cords per controllare il valore (funziona su Chrome e FF con Firebug)

farlo anche subito dopo la chiamata di OnSuccess.

Inoltre, non dimenticare che c'è un codice asincrono in JS (se si usa AJAX per ottenere la posizione), forse semplicemente non si riceve la risposta quando si controlla il valore di x

+0

In realtà lo sto già facendo anche se non ho menzionato :) –

1

Come descritto da Felix King, non puoi restituire un valore da un callback e nella tua variante di variabile globale, la variabile non sarà impostata fino a quando la richiesta AJAX non sarà completata e chiamerà il callback (da qui il suo nome!).

Utilizzando una variabile globale è possibile risolvere il problema se si dispone di una sorta di ciclo di elaborazione, è possibile aggiungere questo codice a quel ciclo per fare ciò che è richiesto ogni volta che il coord cambia.

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

è possibile implementare un metodo di supporto come scorre:

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 
     }); 
    } 

    }; 
Problemi correlati