2010-08-21 10 views
5

Si suppone che restituisca un oggetto JSON contenente un elenco di nomi di file immagine. L'avviso commentato mostra i dati corretti, ma alert(getPicsInFolder("testfolder")); mostra "error".Impossibile ottenere il valore restituito corretto da una chiamata jQuery Ajax

function getPicsInFolder(folder) { 
    return_data = "error"; 
    $.get("getpics.php?folder=" + folder, function (data) { 
    data = jQuery.parseJSON(data); 
    $.each(data, function (index, value) { 
     data[index] = "folders/" + folder + "/" + value; 
    }); 
    //alert(data); // This alert shows the correct data, but that's hardly helpful 
    return_data = data; 
    }); 
    return return_data; 
} 

Cosa sto sbagliando?

risposta

10

Si sta chiamando il metodo asincrono $.get(), in cui verrà richiamata la funzione di richiamata dopo il ritorno della funzione getPicsInFolder(). Seguire i commenti nel seguente esempio:

function getPicsInFolder(folder) { 
    return_data = "error"; 
    // Since the $.get() method is using the asynchronous XMLHttpRequest, it 
    // will not block execution, and will return immediately after it is called, 
    // without waiting for the server to respond. 
    $.get("getpics.php", function (data) { 
     // The code here will be executed only when the server returns 
     // a response to the "getpics.php" request. This may happen several 
     // milliseconds after $.get() is called. 
     return_data = data; 
    }); 

    // This part will be reached before the server responds to the asynchronous 
    // request above. Therefore the getPicsInFolder() function returns "error". 
    return return_data; 
} 

Si dovrebbe prendere in considerazione il refactoring il codice in modo tale che la logica per gestire l'oggetto JSON è nel $.get() callback. Esempio:

$.get("getpics.php?folder=test", function (data) { 
    // Handle your JSON data in here, or call a helper function that 
    // can handle it: 
    handleMyJSON(data); // your helper function 
}); 
+0

Grazie. Chiaramente ho bisogno di ripensare e riscrivere questo. – Dataflashsabot

3

Stai ottenendo i dati in modo asincrono. La funzione di richiamata function (data) {} viene richiamata dopo i ritorni getPicsInFolder.

Sono disponibili due opzioni:

  1. (la cattiva opzione): consente di impostare la chiamata Ajax per essere sincroni.

  2. (l'opzione giusta): ristrutturare il codice, in modo che tutto ciò che deve accadere con i dati di ritorno avviene nella richiamata.

Un modo per farlo sarebbe quello di passare un callback in getPicsInFolder, in questo modo:

function getPicsInFolder(folder, callback) { 
    return_data = "error"; 
    $.get("getpics.php?folder=" + folder, function (data) { 
     data = jQuery.parseJSON(data); 
     $.each(data, function (index, value) { 
      data[index] = "folders/" + folder + "/" + value; 
     }); 
    callback(data); //pass data into the callback function 
}); 

Poi, quando si chiama il vostro getPicsInFolder, invece di fare:

pics = getPicsInFolder('foldername'); 
//do something with pics 

Amento:

getPicsInFolder('foldername', function (pics) { 
    //do something with pics 
}); 
0

Sei confuso su come funziona AJAX. I dati non sono disponibili fino al completamento della richiesta, che avviene dopo che la funzione è stata restituita. E i dati sono disponibili solo all'interno del callback.

1

Le richieste AJAX devono essere asincrone (è in grado di eseguire quelle sincrone al costo di interrompere l'esecuzione e bloccare effettivamente l'interfaccia utente).

getPicsInFolder() restituisce prima che la richiesta AJAX sia stata completata. È necessario per modificare i tuoi UI/gestire l'oggetto JSON restituito l'evento complete (la funzione anonima si sta passando come argomento per $.get()):

$.get("", function() 
{ 
    // This anonymous function will execute once the request has been completed 

    // Update your UI/handle your data here 
}); 

detto che volevo aggiornare un elemento a mio utente ...

$("#ID-of-a-button-in-the-UI").click(function() // executes on click 
{ 
    $.get("url-to-JSON-object", function (json) // executes on request complete 
    { 
     $("#ID-of-element-to-update").html(json.rows[0].key); // updates UI 
    }); 
}); 
+0

È possibile richiedere un XHR per essere sincrono. – strager

+0

@stranger: È vero, è possibile, ma XHR sincrono non può essere AJAX per definizione, dal momento che A in AJAX è per asincrono :) –

+0

Aggiornato la mia risposta. – roosteronacid

Problemi correlati