it-swarm.com.ru

Как вернуть значение из асинхронной функции обратного вызова?

Этот вопрос задают много раз в SO. Но все равно я не могу получить вещи.

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

function foo(address){

      // google map stuff
      geocoder.geocode( { 'address': address}, function(results, status) {
          results[0].geometry.location; // I want to return this value
      })

    }
    foo(); //result should be results[0].geometry.location; value

Если я попытаюсь вернуть это значение, просто получаю "undefined". Я следовал за некоторыми идеями от SO, но все еще терпит неудачу.

Это:

function foo(address){
    var returnvalue;    
    geocoder.geocode( { 'address': address}, function(results, status) {
        returnvalue = results[0].geometry.location; 
    })
    return returnvalue; 
}
foo(); //still undefined
415
Gowri

Это невозможно, поскольку вы не можете вернуться из асинхронного вызова внутри синхронного метода.

В этом случае вам нужно передать обратный вызов в foo, который получит возвращаемое значение

function foo(address, fn){
  geocoder.geocode( { 'address': address}, function(results, status) {
     fn(results[0].geometry.location); 
  });
}

foo("address", function(location){
  alert(location); // this is where you get the return value
});

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

Если у вас много обратных вызовов, вы можете сделать решающий шаг и использовать библиотека обещаний, такая как Q .

420
Sean Kinsey

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

Асинхронные обратные вызовы вызываются браузером или некоторой структурой, такой как библиотека геокодирования Google, когда происходят события. Там нет места для возвращаемых значений, чтобы пойти. Функция обратного вызова может возвращать значение, другими словами, но код, который вызывает функцию, не будет обращать внимание на возвращаемое значение.

21
Pointy

Если вы используете jQuery, вы можете попробовать: http://api.jquery.com/category/deferred-object/

Это позволяет вам отложить выполнение вашей функции обратного вызова до тех пор, пока не будет завершен ajax-запрос (или любая асинхронная операция). Это также можно использовать для вызова обратного вызова после завершения нескольких запросов ajax.

15
Alex Heyd