Probleme mit dem A in AJAX

Gloem

Grünschnabel
Hallo, ich bin noch ziemlich neu in Ajax und hab ein Problem mit der asynchronität.

Ich möchte einen Wert von einer Funktion abfragen und falls dieser Wert noch nicht vorhanden ist, soll ein Request gestellt werden(Traffikminimierung).

Das ganze in Pseudocode:
Code:
doA : function(){ 
    return "bla" + this.doB();
}

doB : function(){
    if (x == null) {
        this.doAjaxRequest();
    }
    return x;
}

doAjaxRequest : function(){
    ...
    onSuccess: function(transport) {
        ...
        this.x = json.x;
    }
}

Das Problem ist jetzt, das doB() eher "undefined" zurückgibt, bevor die Funktion doAjaxRequest() das x gesetzt hat.

Vielleicht hilft die lange Version weiter um mein Problem zu verstehen:

Hauptklasse:
Code:
	_doGetFotos : function() {
		// Erstellen der URL für die Anfrage
		...
		
		// Starten der Anfrage als Ajax-Request
		new Ajax.Request(url, {
			// Benutze das get-Protokoll für die Anfrage
			method: 'get',
			// Wenn erfolgreich -> führe Aktion aus
			onSuccess: function(transport) {
				try {
					function jsonFlickrApi(json){
						if (json.stat != "ok"){
							// something broke!
							return;
						}
						for (i in json.photos.photo) {
							if (typeof json.photos.photo[i] == 'object') {
								var foto = new FlickrFoto(json.photos.photo[i].id, json.photos.photo[i].owner, json.photos.photo[i].secret, json.photos.photo[i].server, json.photos.photo[i].farm, json.photos.photo[i].title, json.photos.photo[i].ispublic, json.photos.photo[i].isfriend, json.photos.photo[i].isfamily);
								GeotaggingShowFotos.flickrFotos.push(foto);
							}
						}
						alert(GeotaggingShowFotos.flickrFotos.length);
						var url = GeotaggingShowFotos.flickrFotos[0].doGetOriginalURL();
						alert(url);
					}
					eval(transport.responseText);
				} catch(e) {
					alert('eval: Ungültiges JSON: ' + e);
					return;
				}
			}
		});
	},

Hier soll nun mit der Zeile
Code:
var url = GeotaggingShowFotos.flickrFotos[0].doGetOriginalURL();
die URL des Fotos in der ursprünglichen Größe abgefragt werden. Dieser Wert kommt allerdings in der ersten Abfrage nicht mit und somit muss eine zweite Anfrage gestellt werden.

Hier mal mein FotoFlickr-Klasse;
Code:
var FlickrFoto = Class.create();
FlickrFoto.prototype = {
	initialize : function(id, owner, secret, server, farm, title, ispublic, isfriend, isfamily) {
		this.id = id;
		this.owner = owner;
		this.secret = secret;
		this.server = server;
		this.farm = farm;
		this.title = title;
		this.ispublic = ispublic;
		this.isfriend = isfriend;
		this.isfamily = isfamily;
		this.infos = null;
	},
	doGetOriginalURL : function() {
		return "http://farm" + this.farm + ".static.flickr.com/" + this.server + "/" + this.id + "_" + this._doGetOSecret() + "_o.jpg";
	},
	_doGetOSecret : function() {
		if (this.infos == null){
			this.infos = new FlickrFotoInfos(this.id, this.secret, this);
		}
		return this.infos.originalsecret;
	}
};

Und die Klasse FlickrFotoInfo
Code:
var FlickrFotoInfos = Class.create();
FlickrFotoInfos.prototype = {
	initialize : function(id, secret) {
		this._doGetFotoInfos(id, secret, flickrFoto);
	},
	_doGetFotoInfos : function(id, secret, flickrFoto) {
		// Erstellen der URL
		...
		// Starten der Anfrage als Ajax-Request
		new Ajax.Request(url, {
			// Benutze das get-Protokoll für die Anfrage
			method: 'get',
			// Wenn erfolgreich -> führe Aktion aus
			onSuccess: function(transport) {
				try {
					function jsonFlickrApi(json){
						if (json.stat != "ok"){
							// something broke!
							return;
						}
						this.originalsecret = json.photo.originalsecret;
					}
					eval(transport.responseText);
				} catch(e) {
					alert('eval: Ungültiges JSON: ' + e);
					return;
				}
			}
		});
	}
};
 
Erstmal, bevor du dich in etwas verrennst:
Ich sehe dort als URL nur ein Adresse von flickr.com....dir ist schon bekannt, dass AJAX nur mit Adressen von demselben Server funktioniert?
 
Das Problem wurde umgangen. Die Anfrage macht der Server, der Request wird umgeleitet. Die Anfragen hauen auch alle hin und ich bekomm genau das zurück was ich haben will, nur eben leider erst nach dem return.
Falls eine Anfrage doch nicht geht, liegt das nur an einem Tippfehler für den Beitrag. Bitte die Anfragen als korrekt ansehen
 
Im Grunde genommen hast du dir die Frage schon selbst beantwortet:

Code:
doB : function(){
    if (x == null) {
        this.doAjaxRequest();
    }
    return x;
}

Asynchron bedeutet ja, dass im Gegensatz zum normalen JS ein Skript weiterarbeiten kann, auch wenn ein Teil dessen(der asynchrone Part->also die Serverabfrage) noch nicht abgeschlossen ist.

Anstatt also den Rückgabewert von doB zu verarbeiten, musst du die Verarbietung von x anstossen, sobald der Request erfolgreich abgeschlossen ist.
 
Indem du die Verarbeitung hier anstösst:
Code:
onSuccess: function(transport) {
       //Request ist abgeschlossen und kann verarbeitet werden
    }
 
Versteh ich leider nicht so ganz. Was meinst du mit verarbeiten?
Da passiert wohl etwas und das etwas wird in einer Variablen gespeichert. Aber wie bekomm ich die Funktion doB dazu auf den Request zu warten?

Ich kann doch schlecht aus dem onSuccess-Teil etwas zurückgeben, oder? Bislang hab ich nach der Verarbeitung immer nur Funktionen aufgerufen die keinen Rückgabewert hatten oder nur Variablen abgespeichert.

Ich möchte einen Wert von einer Funktion abfragen und falls dieser Wert noch nicht vorhanden ist, soll ein Request gestellt werden(Traffikminimierung) und danach der Wert zurückgegeben werden.
 
Das ist es, was ich versuchte, dir zu erklären:

"asynchron" bedeutet, dass die Funktion nicht auf das Ergebnis deines Requests wartet.
Dass man so einen Request asynchron absetzt, hat auch seinen Sinn, denn für die Zeit, bis die Antwort kommt, wäre der Skriptablauf unterbrochen....und so eine Antwort kann schon mal eine Weile dauern.

Es gibt einen optionalen 3. Parameter bei der open()-Methode, wenn der auf "false" gestzt wird, läuft der Request synchron, was den von dir gewnschten Effekt hätte.

Ob und wo man das bei JSON einstellen kann, da bin ich momentan überfragt.
 

Neue Beiträge

Zurück