Javascript присваивает возвращаемое значение функции обратного вызова глобальной переменной

Мой вопрос о Javascript. У меня есть функция обратного вызова, которая получает объект Position при успешном обратном вызове.

Проблема в том, что когда я пытаюсь установить свойства объекта Position на глобальную переменную при успешном обратном вызове, это просто не позволяет мне это делать, а глобальное просто остается undefined.

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

Здесь упрощенный код.

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

Ответы

Ответ 1

Вы не можете вернуть значение из обратного вызова (в данном случае). Это означало бы, что внутри getCurrentPosition должно быть назначено возвращаемое значение из обратного вызова.

Присвоение его глобальной переменной работает, но в то время, когда вы обращаетесь к этой переменной, ей еще не присвоено новое значение. Например.

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

Подумайте об этом: getCurrentPosition, вероятно, выполняет запрос Ajax, чтобы получить позицию. Такой запрос принимает (a) время (пару миллисекунд), и из-за этого (b) является асинхронным, что означает, что JavaScript не дожидается до получения ответа. Ваш код работает быстрее. onSuccess еще не вызывается, когда вы предупреждаете x.

Только решение:

Весь код, который должен получить доступ к позиции для входа или вызова из обратного вызова.

Ответ 2

Как описано Felix King, вы не можете вернуть значение из обратного вызова и в свой вариант глобальной переменной, переменная не будет установлена ​​до тех пор, пока запрос AJAX не завершится и не вызовет обратный вызов (отсюда и его имя!).

Используя глобальную переменную, вы можете решить свою проблему, если у вас есть какой-то цикл обработки, вы можете добавить этот код в этот цикл, чтобы делать то, что требуется, когда изменяется координата.

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

Ответ 3

Вы пытались установить его через глобальный объект 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 

}

также, поскольку вы возвращаете координаты из обработчика успеха, нет ли другого способа получить это значение?

Ответ 4

поместите a console.log(x); сразу после x=cords, чтобы проверить значение (работает с Chrome и FF с FireBug)

сделать это также сразу после вызова OnSuccess.

Также не забывайте, что в JS есть асинхронный код (если вы используете AJAX для получения позиции), возможно, вы просто не получите ответ, когда вы проверите значение x

Ответ 5

Вы можете реализовать вспомогательный метод, например flowing:

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

  };