I JavaScript returnerer alle funksjoner "undefined" med mindre noe annet er spesifisert.
Nå har du jo spesifisert dette med en "return" inni der, og antar selvfølgelig at den returnerer resultatet fra ajax forespørselen når du kjører funksjonen.
Ajax står for "Asynchronous Javascript And XML", ajax er med andre ord asynkront.
Når en funksjon er asynkron så betyr det at funksjonen kjøres med en gang, men gir resultat senere, mens resten av koden fortsetter å kjøre. Asynkrone ting må altså ha en callback hvor resultatet er tilgjengelig ettersom det ikke stanser tråden.
I JavaScript gjelder dette stort sett timere, ajax, websockets og en del andre ting.
Her er et eksempel som forhåpentligvis er enklere å forstå
PHP:
var test = 0;
setTimeout(function() {
test = 1;
}, 1000);
console.log( test ); // fortsatt 0, variablen endres ikke før om et sekund ?
Timeouten venter 1 sekund, og så endres variablen, men resten av koden fortsetter likevel å kjøre. Det er det som er akynkron oppførsel.
Ajax er noe av det samme
PHP:
var request = new XMLHttpRequest();
request.open('get', 'java.php', true);
// den siste parameteren ovenfor, "true", angir om forespørselen er synkron eller asynkron
// Denne skal alltid settes til true, synkron ajax er en uting, og er i utgangspunktet aldri tillatt.
request.onreadystatechange = function () {
// legg merke til at dette er callback'en, den trigger på alle endringer i forspørselen, og 4 betyr at resultatet er mottatt
if ( request.readyState === 4 && request.status === 200) {
// du kan rett og slett ikke returnerer herfra, denne callback'en kjøres senere
var response = request.responseText;
}
}
request.send(null);
og det er kanskje enda lettere å forstå med XMLHttpRequest i jQuery
PHP:
$.ajax({
url : 'java.php'
}).done(function(response) { // callback
// response er kun tilgjengelig her
});
// ikke her
Så hva er løsningen, hvordan får man resultatet tilbake fra en funksjon?
Den eneste løsninger er callbacks, enten det er i form av promises eller vanlige funksjoner, og koden må skrives slik at den fungerer med callbacks, som kan være litt plundrete noen ganger, men man må vente på at XMLHttpRequest kontakter "java.php" i bakgrunnen og laster inn innholdet i den filen, man har ikke noe annet valg.
PHP:
function javaFunc(callback) {
var javaRequest = new XMLHttpRequest();
javaRequest.open('get', 'java.php', true);
javaRequest.onreadystatechange = function () {
if (javaRequest.readyState === 4 && javaRequest.status === 200) {
callback( javaRequest.responseText );
}
}
}
javaRequest.send(null);
}
javaFunc(function(data) {
document.getElementById("java").innerHTML = data;
});
Dette er noe alle som begynner med JavaScript treffer på før eller siden, og alle gjør stort sett samme feilen.
På Stack Overflow har Felix fra Facebook vært så hyggelig å lage en slags kanonisk guide til asynkrone funksjoner, hvordan de virker, og hvordan man jobber med de, nettopp fordi det samme spørsmålet kommer opp hundre ganger hver eneste dag fra nye utviklere som støter på det samme problemet i forskjellige former
http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-asynchronous-call
.