2011-01-02 30 views
9

Estoy seguro de que conoce este problema, todavía estoy tratando de resolverlo durante unos días. He intentado muchas cosas pero nadie trabajaba:jquery ajax return: undefined

Este es el código

function lobbyLeader() { 
    $.ajax({ 
     data: {"id": 1, "request": "lobbyinfo", "method": "read"}, 
     url: 'api.php', 
     dataType: 'json', 
     success: function(data){ 
      result = data.leader; 
      return result; 
     } 
    }); 
} 

alert(result); mostrará 1 pero cuando se utiliza en una otra función que dice undefined.

+0

¿Qué quiere decir con "al usar en otra función"? –

+0

¿Estás haciendo 'alert (lobbyLeader());' y obteniendo 'undefined'? –

+0

"¿Estás alerta (lobbyLeader()) y estás indefinido?" Sí – Nightbox

Respuesta

8

No puede return desde una función asíncrona como esta, usted está regresando de esa función de devolución de llamada success, no de la función primaria. En su lugar, quítese todo lo que necesita en la devolución de llamada, así:

function lobbyLeader() { 
    $.ajax({ 
    data: {"id": 1, "request": "lobbyinfo", "method": "read"}, 
    url: 'api.php', 
    dataType: 'json', 
    success: function(data){ 
     someOtherFunc(data.leader); 
    } 
}); 
} 
+0

He combinado ambas funciones: http://pastebin.com/runiGzsd ¿me puede decir cómo solucionarlo realmente? – Nightbox

+0

@Nightbox - En lugar de 'if (función (data.leader) {' necesita 'if (data.leader) {' –

+0

Untaught SyntaxError: Token inesperado == http://pastebin.com/DN8Zk34G – Nightbox

4

El problema aquí es que AJAX es asíncrono (es lo que representa la primera A). Esto significa que la función regresa inmediatamente; el controlador success solo se invoca cuando la solicitud es exitosa. Esto significa que lobbyLeader regresa inmediatamente después de haber realizado su solicitud, por lo que no devuelve nada.

Si tiene algún código que deba ejecutarse después de haber recibido los datos, debe colocarse en el controlador success (o another AJAX event handler) o ser invocado por este.

1

cuando se return valores desde dentro de una función anónima que se ejecuta de forma asíncrona, esos valores no se propagan por la cadena de ámbito, la declaración return es solamente aplicado en el alcance de la función actual, no en el ámbito circundante, $.ajax() es asíncrono, por lo que inmediatamente después de ejecutar la declaración, la función externa regresa, por lo que no hay un valor de retorno de la función externa, por eso obtienes undefined.

La única manera de enganchar en un posible valor de retorno de la función de devolución de llamada pasada a $.ajax es invocar otra función externa, pasando los datos deseados.

2

Lo recomiendo.

  1. utiliza la llamada ajax mediante async: false.
  2. mueve la declaración de devolución después de la llamada ajax.

Ejemplo:

function makeJQGridDataFromList(url) 
{ 
    var rowData; 
    var viewPage = 0; 
    var viewTotal = 0; 
    var viewRecords = 0; 

    var resultObject; 

    $.ajax({  
     type:"GET", 
     url:url,  
     async: false, 
     success:function(args){ 
      if(args.result==true) 
      { 
       try 
       { 
        viewPage = args.cond.pageIndex; 
        viewTotal = args.cond.recordCountPerPage; 
        viewRecords = args.cond.totalCnt; 

        rowData = jsonMakeRowsForGrid(args.data); 
       } 
       catch (e) 
       { 
        console.debug("Error!"); 
        alert("Invalid data"); 
        return; 
       } 
      } else 
      { 
       alert("API return ERROR!"); 
       return; 
      } 
     }, 
     error:function(e){ 
      alert("Fail AJAX communication"); 
      return; 
     } 
    }); 

    resultObject = { 
     page : viewPage, 
     total : viewTotal, 
     records : viewRecords, 
     rows : rowData 
    }; 

    return(resultObject); 
} 

Se puede probar el siguiente método.

(En el otro archivo (HTML o JS))

var gridData = makeJQGridDataFromList(openAPIUrl); 
console.debug(">> " + JSON.stringify(gridData)); 

Se puede ver la gridData.

Me enfrenté a los mismos problemas.:)

1

Correctamente indicado que no se puede regresar realmente del éxito, sin embargo, si se está haciendo lo que creo que se está haciendo, y es capturar los datos y devolverlos y asignarlos a otra área IE

var obj = lobbyLeader();

Luego puede establecer la función en async: false y devolver el obj fuera del éxito después de que el código haya terminado de ejecutarse. ejemplo

function lobbyLeader() { 
var obj; 
    $.ajax({ 
    async:false; 
    data: {"id": 1, "request": "lobbyinfo", "method": "read"}, 
    url: 'api.php', 
    dataType: 'json', 
    success: function(data){ 
     obj= JSON.parse(data); 
    } 
}); 
    return obj; 
} 

De esta manera la secuencia de comandos se detiene para esperar el éxito y luego establece y vuelve.

+0

"A partir de jQuery 1.8 [hace tres años!] el uso de async: falso con jqXHR ($ .Deferred) está en desuso, debe usar las opciones de éxito/error/devolución de llamada completa en lugar de los métodos correspondientes del objeto jqXHR como jqXHR.done() o el jqXHR.success() en desuso. http://api.jquery.com/jQuery.ajax/ Las promesas no son tan difíciles de aprender, vale la pena el esfuerzo. Sin duda una mejora al solo bloquear toda su UI hasta que la solicitud se complete. –

Cuestiones relacionadas