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

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

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

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
+427
источник поделиться
3 ответа

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

В этом случае вам нужно передать обратный вызов 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.

+434
источник

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

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

+22
источник
другие ответы

Связанные вопросы


Похожие вопросы

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

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

+15
источник

Посмотрите другие вопросы по меткам или Задайте вопрос