JS za bardzo się spieszy...

0

No więc mam funkcję wysyłającą zapytanie HTTP GET. Może nie jest piękna, ale działa.

     
  var resp2; // zmienna globalna

   function SendGet(dest,params){
                
            	var xmlhttp = new XMLHttpRequest();
		var out;

		if (xmlhttp === null)
		{
			alert('AJAX not supported');
		}

		xmlhttp.onreadystatechange = function ()
		{
			if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
			{
				out = xmlhttp.responseText;
                                resp2 = out; // zmienna globalna
				return out;
			}
		};
                
		xmlhttp.open("GET", dest+"?"+params, true);
		xmlhttp.setRequestHeader("Connection", "close");
		xmlhttp.send(params);            
            
        }

Problem pojawia się kiedy próbuję odwołać się do wyniku funkcji:

var resp = SendGet(strona,parametry);
alert(resp);

wyrzuca undefined

Po prostu wynik jest przypisywany do zmiennej zanim jeszcze funkcja się wykonała. Zanim SendGet zwróci wynik, Javascript wykonuje już kolejne instrukcje! Dłubałem już trochę w innych językach i z czymś takim spotykam się pierwszy raz.

Mały teścik przy użyciu zmiennej globalnej (resp2):

var resp = SendGet(strona,parametry);
alert(resp2); // wyrzuca undefined - nie przyszła jeszcze odpowiedź z serwera...
alert(resp);  //  wyrzuca undefined - w końcu ta zmienna została przypisana do wyniku niewykonanej funkcji
alert(resp2); // wyrzuca wynik! - funkcja SendGet() już się wykonała

Jedyne rozwiązanie do jakiego doszedłem to przy użyciu zmiennej globalnej i arbitralnie dobranego opóźnienia:

      SendGet(strona,parametry);
                setTimeout(function(){alert(resp2)},3000); 

Próbowałem też tak ,ale to powoduje zawieszenie się skryptu, a w JS z tego co słyszałem nie ma wait()/sleep():

SendGet(strona,parametry);
                 var i;
                 while(typeof(resp2)=== 'undefined'){
                   i++;}

A ja chcę po prostu pobrać wynik funkcji zaraz po jej wykonaniu. Czy to takie trudne?

0

Poczytaj o callback-ach:

   function SendGet(dest, params, callback){
 
                var xmlhttp = new XMLHttpRequest();
                var out;
 
                if (xmlhttp === null)
                {
                        alert('AJAX not supported');
                }
 
                xmlhttp.onreadystatechange = function ()
                {
                        if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
                        {
                                out = xmlhttp.responseText;
                                callback(out);
                        }
                };
 
                xmlhttp.open("GET", dest+"?"+params, true);
                xmlhttp.setRequestHeader("Connection", "close");
                xmlhttp.send(params);            
        }

Btw, imo robisz za duże wcięcia.

1 użytkowników online, w tym zalogowanych: 0, gości: 1