Подтвердить что ты не робот

Ожидание обратного вызова в javascript

Я пытаюсь создать функцию, которая возвращает объект с информацией обратного вызова:

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

Как я могу это сделать? Функция getLocation возвращает значение null до successful.

Спасибо!

4b9b3361

Ответ 1

Обратные вызовы используются, потому что функция асинхронна. Обратный вызов выполняется в какой-то момент в будущем.

Итак, да getLocation возвращается до срабатывания обратного вызова. То, как работают асинхронные методы.

Вы не можете дождаться обратного вызова, это не то, как он работает. Вы можете добавить обратный вызов к getLocation, который запускается после его завершения.

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

Теперь вместо того, чтобы делать var x = getLocation() и ожидая возвращаемого значения, вы вызываете его следующим образом:

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

Ответ 2

Я бы рекомендовал подход в Rocket-ответе. Однако, если вы действительно этого захотите, вы можете запустить остальную часть своего кода, когда getLocation закончит работу с помощью отложенного объекта jQuery. Это даст вам более тонкий контроль, чем просто использование обратных вызовов, предоставляемых 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
    });