JavaScript Variablenproblem

da_freak

Well-known member
ID: 233028
L
22 Juni 2006
736
56
Hallo,

wahrscheinlich ist das ein ganz simples Problem, aber ich habe keine Ahnung, wonach ich googeln soll um da von selbst drauf zu kommen, zumal da etwas ganz seltsam dran ist. Also erstmal mein Code:

Code:
function getQuoteTags(){
	ret = "";
	$.ajax({
		type: "GET",
	   url: "suggestions.php",
	   data: "fn=getQuotes",
	   success: function(msg){
		 ret = msg;
	 }
	});
        //alert(ret)
	return ret;
}

function StateSuggestions() {
	var tags = getQuoteTags();
	this.states = tags.split(",");
}

Ich will für eine Autocomplete-Funktionalität (die auch an sich einwandfrei funktioniert), Tags aus der Datenbank laden. Das mache ich hier mit dem JQuery Ajax-Schnipsel. Das funktioniert ebenfalls einwandfrei. Das Problem ist allerdings, dass ich den Inhalt von der msg-variablen in die mir das Ajax Ergebnis geliefert wird, nicht an die aufrufende funktion geliefert bekomme.
Wenn ich jetzt in dem Beispiel, vor dem return ret; das alert(ret); ausführe, bekomme ich zwar ein leeres Alertfenster, aber der String wird einwandfrei zurückgegeben und weiterverarbeitet. Und ich glaube genau das macht mein Problem zu speziell um es zu googeln. Wie gesagt: Vermutlich nur eine Kleinigkeit. Um einen Hinweis oder Hilfestellung wär ich allerdings sehr dankbar!
 
Ajax= Asynchrones javascript and XML

dein return ret wird direkt nach dem Ajax-Aufruf durchgeführt, also noch bevor du eine Antwort bekommst.

Demnach mußt du dein

this.states = tags.split(",");

innerhalb des Ajax ausführen, oder dort eine Funktion aufrufen, die das macht.

Code:
function getQuoteTags(){

    $.ajax({
        type: "GET",
       url: "suggestions.php",
       data: "fn=getQuotes",
       success: function(msg){
    doit(msg);
     }
    });
}

function doit(tags) {
    this.states = tags.split(",");
}

und einfach getQuoteTags() aufrufen.
 
Hmmm, das hatte ich auch schon probiert, funktioniert allerdings auch nicht.

Ich habe folgendes Tutorial benutzt: https://www.webreference.com/programming/javascript/ncz/column2/

Beispielseite:
https://www.webreference.com/programming/javascript/ncz/column2/example2.html

Code:
https://www.webreference.com/programming/javascript/ncz/column2/autosuggest2.js

https://www.webreference.com/programming/javascript/ncz/column2/suggestions2.js

Um die datei suggestions2.js gehts hier quasi. In dem Beispiel wird das array in der function erzeugt. In der Seite, in der der Autosuggester dann auf die entsprechende input-box losgelassen wird, wird übrigens folgendes JS ausgeführt:

Code:
        <script type="text/javascript">
            window.onload = function () {
                var oTextbox = new AutoSuggestControl(document.getElementById("txt1"), new StateSuggestions());
            }
        </script>

Liegt es vielleicht daran, dass mit this.states durch das erzeugen eines Objekts mit new StateSuggestions nur innerhalb dieses Objekts sprich hier:

Code:
function StateSuggestions() {
...
}

gearbeitet weden kann?
 
Ich hab die Lösung gefunden:

Code:
function getQuoteTags(obj){
	$.ajax({
		type: "GET",
	   url: "suggestions.php",
	   data: "fn=getQuotes",
	   success: function(msg){
		obj.states = msg.split(","); //<---
	 }
	});
}

function StateSuggestions() {	
	getQuoteTags(this); //<---
	alert(this.states.length);
}


Aber was mich immer noch stutzig macht, ist die Tatsache, dass ich (siehe 1. post) die Variable korrekt zurückgeben kann, wenn ich vorher ein alert(ret) mache
 
Syntaktisch ist die Variable ja vorher definiert.
Praktisch hast du lediglich Glück, wenn du das Ergebnis da schon hast.

Bau mal n Sleep vor dem Setzen von ret im AJAX-Return ein, dann merkst du, dass ret immer noch leer is, du den Leerstring zurückgibst und ne halbe Minute später erst vom AJAX-Return gesetzt wird.
 
Ich bin jetzt einigermaßen durchgestiegen. Mit Glück hat das glaub ich weniger zu tun, weil das reproduzierbar ist. Durch die asynchronität läuft der AJAX teil wohl immer weiter und scheinbar bricht ein alert(); das ab und die Variablen werden gesetzt. Das kann man aber folgendermaßen vermeiden: async: false,
 
Und was den Browser (soweit ich das weiß) auch lahmlegen kann. Zumindest wird beim Dojotoolkit davor gewarnt das zu nutzen.
 
Firefox erkennt Scripte, die nicht mehr reagieren, warnt mich und gibt mir die Möglichkeit, die abzubrechen. Wenn dieses Dialogfenster aber einmal auf einer Webseite aufgeht, @da_freak, sei versichert, dass ich dann diese Seite nie wieder besuche ;)

Sinn von AJAX ist ja, dass es eben AJAX is.

AJAX-Programmierung hat dieselben Tücken wie multi-threaded-Programmierung: Jeder AJAX-Request ist wie ein neuer Thread zu behandeln. Man weiß nie, wann er fertig wird. Du musst damit die Anwendung so schreiben, dass auch ohne seine Rückkehr sie korrekt funktioniert.
 
Aber ob das immer klappt? Bzw. wie schnell FF das meldet...
Die Frage ist ja ab wann er meint, das ein Script nicht läuft.

Habe mal getestet und in den Openlayers (sowas wie google Maps) 10k Elemente gefügt, die per Ajax kamen. Chrome hats in paar Sek. geschafft, FF hat ~30 Sek. gebraucht, Ie hats gar nicht gepakt. Beim FF kam aber keine Meldung obwohl ich nichts machen konnte. Wohl weil das Script ja gearbeitet hat.
 
Habe mal getestet und in den Openlayers (sowas wie google Maps) 10k Elemente gefügt, die per Ajax kamen.
10k? Is ja gar nix :biggrin: Ich hab für meine Diplomarbeit schon n paar Stück mehr gehabt. Allerdings hab ich nicht per AJAX laden lassen, sondern eben n viele-MB-dickes HTML-Dokument mit 99,999% JavaScript gehabt :mrgreen:

Firefox hat mir mehrfach - jeweils nach ner gefühlten halben Minute - dann diese Warnung gezeigt. Ich hab das Script da natürlich nicht beendet, weil ich es ja kannte und wusste, dass es irgendwann fertig wird.

Wenn Firefox mit einem sychronen AJAX-Request nicht mehr reagiert, die Warnung aber nicht zeigt, klingt mir das nach einem Bug in Firefox.
 
danke für den Einwand, tH. Ich hab das async:false; wieder rausgenommen und das mit einem Aufruf an eine Funktion außerhalb des requests gemacht, so wie es Bububoomt schon vorgeschlagen hat. Keine Ahnung warum das nicht funktioniert hatte, entweder nicht zu Ende gedacht oder von mir falsch umgesetzt. Mittlerweile geht's auch damit.
 
War ja nur zu Demonstrationszwecken. Ich hab halt 15 Minuten vor meinem Vortrag die Seite laden lassen... 8) :mrgreen: