Ожидание обратного вызова в 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
.
Спасибо!
Ответы
Ответ 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
});