¿Cómo devolver el valor de una función de devolución de llamada asincrónica? [duplicar]

527

Esta pregunta se hace muchas veces en SO. Pero todavía no puedo conseguir cosas.

Quiero obtener algún valor de la devolución de llamada. Mire el guión a continuación para obtener una aclaración.

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

Si trato de devolver ese valor, simplemente obtengo "indefinido". Seguí algunas ideas de SO, pero aún falla.

Esos son:

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

Esto es imposible porque no puede regresar de una llamada asincrónica dentro de un método sincrónico.

En este caso, debe pasar una devolución de llamada a foo que recibirá el valor de retorno

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

La cuestión es que, si una llamada de función interna es asincrónica, entonces todas las funciones que 'envuelven' esta llamada también deben ser asincrónicas para 'devolver' una respuesta.

Si usted tiene una gran cantidad de devoluciones de llamada que podría considerar dar el paso y utilizar una biblioteca de promesa como Q .

8
  • 4
    :) No es fuerte, es como es. Tan pronto como utilice un método asincrónico para pasar datos, toda la cadena de funciones se volverá asincrónica. 27/07/11 a las 16:31
  • 2
    Vota a favor por finalmente hacer que esto tenga sentido. 13 feb.15 a las 19:28
  • 6
    "no se puede utilizar una llamada asincrónica dentro de un método sincrónico". - Sí tu puedes. Simplemente no puede usar el resultado de la llamada asíncrona desde el mismo método sincrónico.
    nnnnnn
    7/07/2016 a las 22:48
  • 4
    @Sean Kinsey, ¿puede decirme cómo acceder a la variable de ubicación fuera de la función foo ()? 29 de agosto de 2016 a las 7:39
  • 1
    Para que quede claro, esto no le permitirá "devolver" el valor de esa variable de una manera que PHP lo devuelva. Básicamente, estamos pasando el resultado de una función de devolución de llamada a otra función de devolución de llamada. Todavía no hay una var externa que realmente contenga el resultado ... 27 de junio de 2018 a las 1:38
30

No tiene sentido devolver valores de una devolución de llamada. En su lugar, haga el trabajo "foo ()" que desea hacer dentro de su devolución de llamada.

Las devoluciones de llamada asincrónicas son invocadas por el navegador o por algún marco como la biblioteca de codificación geográfica de Google cuando ocurren eventos. No hay lugar para los valores devueltos. Una función de devolución de llamada puede devolver un valor, en otras palabras, pero el código que llama a la función no prestará atención al valor de retorno.

0
dieciséis

Si está utilizando jQuery, es posible que desee intentarlo : http://api.jquery.com/category/deferred-object/

Le permite diferir la ejecución de su función de devolución de llamada hasta que se complete la solicitud ajax (o cualquier operación asíncrona). Esto también se puede usar para llamar a una devolución de llamada una vez que se hayan completado varias solicitudes ajax.