2011-01-02 25 views
9

Jestem pewien, że znasz ten problem, wciąż próbuję go rozwiązać przez kilka dni. Próbowałem wiele rzeczy, ale nikt nie pracował:jquery ajax return: undefined

Oto kod

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); pokaże 1 ale przy stosowaniu w innej funkcji mówi undefined.

+0

Co masz na myśli przez "podczas używania w innej funkcji"? –

+0

Czy robisz 'alert (lobbyLeader());' i odzyskiwanie 'undefined'? –

+0

"Czy robisz alert (lobbyLeader()) i powracasz niezdefiniowany?" Tak – Nightbox

Odpowiedz

8

Nie można return z asynchronicznej funkcji w ten sposób, wracasz z tej funkcji wywołania zwrotnego success, a nie funkcji nadrzędnej. Zamiast kopać co trzeba w zwrotnego, tak:

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

Połączyłem obie funkcje: http://pastebin.com/runiGzsd czy możesz mi powiedzieć, jak to naprawić? – Nightbox

+0

@Nightbox - Zamiast 'if (function (data.leader) {' potrzebujesz 'if (data.leader) {' –

+0

Uncaught SyntaxError: Niespodziewany token == http://pastebin.com/DN8Zk34G – Nightbox

4

Problem polega na tym, że AJAX jest asynchroniczny (tak samo jak pierwszy A). Oznacza to, że funkcja zwraca się natychmiast; Procedura obsługi success jest wywoływana tylko wtedy, gdy żądanie zakończyło się pomyślnie. Oznacza to, że lobbyLeader powraca natychmiast po zgłoszeniu, więc nic nie zwraca.

Jeśli masz kod, który musi zostać uruchomiony po otrzymaniu danych, musi zostać umieszczony w module obsługi success (lub another AJAX event handler) lub może zostać przez niego wywołany.

1

kiedy return wartości od wewnątrz anonimowej funkcji, który jest wykonywany asynchronicznie, te wartości nie będą propogate górę łańcucha zakres, oświadczenie return jest tylko zastosowany do bieżącego zakresu funkcji, a nie do otaczającego zakresu, $.ajax() jest asynchroniczny, więc natychmiast po wykonaniu instrukcji funkcja zewnętrzna zwraca, więc nie ma zwracanej wartości funkcji zewnętrznej, dlatego uzyskujesz undefined.

Jedynym sposobem, aby połączyć się z możliwą wartością zwrotną z funkcji zwrotnej przekazywanej do $.ajax, jest wywołanie innej funkcji zewnętrznej, przekazując pożądane dane.

2

Polecam w ten sposób.

  1. użyć wywołania ajax przez async: false.
  2. przesuń instrukcję return po wywołaniu ajax.

przykład:

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

można przetestować w następujący sposób.

(w innym pliku (html lub js))

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

Można oglądnąć gridData.

Stawiłem czoła tym samym problemom.:)

1

Prawidłowo stwierdzono, że nie można naprawdę powrócić z sukcesu, jeśli robisz to, co myślę, że robisz, a to jest chwytanie danych i zwracanie ich oraz przypisywanie do czegoś w innym obszarze IE

var obj = lobbyLeader();

Następnie można po prostu ustawić funkcję async: false i zwrócić obiekt poza sukcesem po zakończeniu kodu. przykład

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

ten sposób skrypt przestaje czekać na sukces, a następnie ustawia i powroty.

+0

"Jak z jQuery 1,8 [trzy lata temu!] użycie async: false z jqXHR ($ .Deferred) jest przestarzałe, musisz użyć opcji success/error/complete callback zamiast odpowiednich metod obiektu jqXHR, takich jak jqXHR.done() lub przestarzała jqXHR.success(). " http://api.jquery.com/jQuery.ajax/ Obietnice nie są aż tak trudne do nauczenia, warte wysiłku. Z pewnością ulepszenie polegające na zablokowaniu całego interfejsu użytkownika do czasu zakończenia żądania. –