NeoXx hat mich zwar per PM gefragt, aber ich denke es ist von allgemeinen Interesse:
NeoXx said:
Leider hab ich jetzt nach 2 Tagen suchen immer noch keinen Plan was Thread Save genau bedeutet und wie eine save Funktion auszusehen hat.
Evtl. liegt es einfach daran, daß es
Thread-Safe heißt. Mein Englisch ist nicht immer so gut, daß ich das zu unterscheiden wüßte.
Bei Deinem Code geht es vorallem um den "reantrance". Also das nochmalige Aufrufen der Funktion obwohl der erste Aufruf noch nicht durchgearbeitet ist. Dabei werden durch den 2.Aufruf die Daten des ersten überschrieben und können in einen undefinierbaren Zustand führen sobald der XML-Request abgearbeitet wurde.
Die entsprechende Lösung heißt "Objektorientierte Kapselung".
Hier stößt man aber an Probleme der OOP, da ja die aufzurufende Funktion ebenfalls in das Objekt gekapselt werden muß. JavaScript erlaubt dies aber Mithilfe des Prototypings.
Hier nun ein (lauffähiger) Ausschnitt aus meiner ajax.js.
Die Funktion get_XMLhttpObject() gibt es als Einzelfunktion, da in meiner Lib verschiedene Ajax-Funktionen existieren, die dem Programmierer bereits möglichst viel abnehmen sollen. (Z.B. Bilder nachladen, Select-Boxen ändern, HTML nachladen, etc.) Ich habe auf die allgemeine AJAX_callFunction() gekürzt, die eine externe Funktion mit dem fertig geladenen XML-Objekt aufruft.
Für das Umwandeln des onreadychange-Handlers in das Objekt wird der bind-Prototyp gebraucht.
Code:
function get_XMLhttpObject() {
//XMLHttpRequest-Objekt erzeugen
var xmlhttp;
try {
xmlhttp = new XMLHttpRequest();
}
catch (e1) {
try {
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e2) {
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e3) {
}
}
}
if (! xmlhttp) {
alert("Der Browser unterstützt kein XMLHttpRequest!");
}
return xmlhttp;
}
Function.prototype.bind = function(object) {
var __method = this;
return function() {
return __method.apply(object, arguments);
}
}
/* Multi-Threadable-AJAX */
function AJAX_callFunction(url, postparam, func) {
// Funktion ins Objekt speichern:
this.func = func;
// XML-Objekt:
this.xmlhttp = get_XMLhttpObject();
if (this.xmlhttp) {
// HTTP-Request
if (postparam) {
this.xmlhttp.open("POST", url, true);
this.xmlhttp.send(postparam);
} else {
this.xmlhttp.open("GET", url, true);
this.xmlhttp.send(null);
}
// Warten bis fertig (asyncron)
this.xmlhttp.onreadystatechange = (function () {
if (this.xmlhttp.readyState == 4) {
if (this.xmlhttp.status == 200) {
this.func(this.xmlhttp);
} else {
alert("Fehler im AJAX-Request:\n"+this.xmlhttp.responseText);
}
}
}).bind(this);
}
}
Ein Aufruf sieht dann wie folgt aus:
Code:
// ein GET-Request:
new AJAX_callFunction(window.location.baseref+'ajax.php?Command=getListOfDB'', changeListOfDB)
// oder als POST-Request:
new AJAX_callFunction(window.location.baseref+'ajax.php', 'Command=getListOfDB', changeListOfDB)
// und noch die Funktion zum Auswerten:
function changeListOfDB(xmlhttp) {
text = xmlhttp.responseText;
...
}
huschi.