web-dev-qa-db-fra.com

Attendre le rappel en javascript

J'essaie de créer une fonction qui renvoie un objet avec des informations de rappel:

var geoloc;

var successful = function (position) {
    geoloc = {
        longitude: position.coords.longitude,
        latitude: position.coords.latitude
    };
};

var getLocation = function () {
    navigator.geolocation.getCurrentPosition(successful, function () {
        alert("fail");
    });

    return geoloc;
};

Comment puis-je faire ceci? La fonction getLocation renvoie une valeur nulle avant l'exécution de successful.

Merci!

20
palvarez89

Les rappels sont utilisés car la fonction est asynchrone. Le rappel s'exécute à un moment donné dans le futur.

Donc, oui getLocation retourne avant que le rappel ne soit déclenché. Voilà comment fonctionnent les méthodes asynchrones.

Vous ne pouvez pas attendre le rappel, ce n'est pas ainsi que cela fonctionne. Vous pouvez ajouter un rappel à getLocation, qui s'exécute une fois terminé.

var getLocation = function(callback){
    navigator.geolocation.getCurrentPosition(function(pos){
        succesfull(pos);
        typeof callback === 'function' && callback(geoloc);
    }, function(){
        alert("fail");
    });
};

Maintenant, au lieu de faire var x = getLocation() et d'attendre une valeur de retour, vous l'appelez comme ceci:

getLocation(function(pos){
    console.log(pos.longitude, pos.latitude);
});
25
Rocket Hazmat

Je recommanderais l'approche dans la réponse de Rocket. Cependant, si vous le vouliez vraiment, vous pourriez déclencher le reste de votre code lorsque le getLocation se termine en utilisant un objet différé jQuery. Cela vous donnera un contrôle plus fin que l'utilisation des rappels fournis par getCurrentPosition.

// create a new deferred object
var deferred = $.Deferred();

var success = function (position) {
    // resolve the deferred with your object as the data
    deferred.resolve({
        longitude: position.coords.longitude,
        latitude: position.coords.latitude
    });
};

var fail = function () {
    // reject the deferred with an error message
    deferred.reject('failed!');
};

var getLocation = function () {
    navigator.geolocation.getCurrentPosition(success, fail); 

    return deferred.promise(); // return a promise
};

// then you would use it like this:
getLocation().then(
    function (location) {
         // success, location is the object you passed to resolve
    }, 
    function (errorMessage) {
         // fail, errorMessage is the string you passed to reject
    }); 
20
jbabey