[JS/AJAX] ajax response als returnwaarde aangeroepen functie

Pagina: 1
Acties:
  • 208 views sinds 30-01-2008
  • Reageer

  • JozyDaPozy
  • Registratie: December 2002
  • Laatst online: 17-02 08:27
Ik wil graag een functie maken waarmee ik een AJAX-request doe, en dan ook de response als return-waarde van die functie heb.

Theoretisch lukt het me, maar in praktijk niet.

Mijn code:
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var jvpajax_result = '';

var handlerFunc = function(t) {
    jvpajax_result = t.responseText;
}

var errFunc = function(t) {
    jvpalax_result = 'Error ' + t.status + ' -- ' + t.statusText;
}

function AjaxGetContent(url) {
    jvpajax_result = '';
    new Ajax.Request(url, {parameters:'thisvar=true&thatvar=Howdy', onSuccess:handlerFunc, onFailure:errFunc});         
        
    while (jvpajax_result == '') {
      // wachten
    }
    return jvpajax_result;
}

Als ik deze code nu uitvoer, dan blijft mijn browser 'hangen' en geeft de melding: 'script blijft hangen. wil je het script stoppen?'
Vervolgens kies ik dan voor NEE, en direct daarna heb ik mijn juiste return value.
Dit is uiteraard geen gewenste oplossing.

Als ik VOOR het while-loopje een alert zet, dan krijg ik die netjes te zien, en als ik dan op OK klik, geeft mijn functie ook direct de return-value terug.

Ik begrijp het probleem. De browser is zo hard bezig met de while dat ie geen 'tijd' heeft om de request netjes af te handelen, en zodra er dus een alert is, of zo'n script-stop-melding kan hij op dat moment de request afhandelen, en de jvpajax_result invullen.

Maar hoe los ik dit op?

Ik begrijp dat de A van AJAX voor Asynchroom staat, maar het zou toch moeten kunnen op enige manier.

Ik wil heel graag de functie wel op deze manier gebruiken, en niet in de handler-functie een div-je vullen ofzo. Het zou namelijk allemaal een stuk handiger werken als ik gewoon direct responses kan gebruiken van functies, aangezien ik de data in de response ook verder met javascript wil bewerken.

offtopic:
Ik gebruik nu trouwens Prototype voor de afhandeling van het AJAX-gebeuren, maar het probleem doet zich uiteraard ook voor als ik een zelfgeschreven AJAX-functie gebruik

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 20:34

crisp

Devver

Pixelated

Als je meteen de response terug wilt krijgen moet je een synchroon request doen en geen asynchroon, dat is gewoon hoe het werkt en niet anders.

Intentionally left blank


  • JozyDaPozy
  • Registratie: December 2002
  • Laatst online: 17-02 08:27
crisp schreef op zaterdag 06 mei 2006 @ 18:20:
Als je meteen de response terug wilt krijgen moet je een synchroon request doen en geen asynchroon, dat is gewoon hoe het werkt en niet anders.
En dat is mogelijk op een soortgelijke wijze met javascript?

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 20:34

crisp

Devver

Pixelated

JozyDaPozy schreef op zaterdag 06 mei 2006 @ 18:21:
[...]

En dat is mogelijk op een soortgelijke wijze met javascript?
ja

Intentionally left blank


  • JozyDaPozy
  • Registratie: December 2002
  • Laatst online: 17-02 08:27
Ew ;)
Kun je me iets verder helpen dan, aangezien het klinkt alsof jij weet hoe het moet. Ik ken het bestaan niet van deze functionaliteit en weet niet zo goed waar ik op moet zoeken.

edit:
zojuist de oplossing gevonden ;)
ik post 'm zo

[ Voor 10% gewijzigd door JozyDaPozy op 06-05-2006 18:47 ]


  • JozyDaPozy
  • Registratie: December 2002
  • Laatst online: 17-02 08:27
Het bleek vrij eenvoudig (als je weet hoe het moet ;))

Hiermee lukt het me nu wel:
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
var xmlhttp=false;
/*@cc_on @*/
/*@if (@_jscript_version >= 5)
// JScript gives us Conditional compilation, we can cope with old IE versions.
// and security blocked creation of the objects.
 try {
  xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
 } catch (e) {
  try {
   xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
  } catch (E) {
   xmlhttp = false;
  }
 }
@end @*/
if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
    try {
        xmlhttp = new XMLHttpRequest();
    } catch (e) {
        xmlhttp=false;
    }
}
if (!xmlhttp && window.createRequest) {
    try {
        xmlhttp = window.createRequest();
    } catch (e) {
        xmlhttp=false;
    }
}

function AjaxGetContent(url) {
    xmlhttp.open("GET", url,false);
    xmlhttp.send(null);
    return xmlhttp.responseText;
}


de 3e variabele van de open() functie staat voor async, als je deze op FALSE zet, returned de send() pas zodra de content binnen is.
Gevonden via: http://www.w3schools.com/dom/dom_http.asp

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 20:34

crisp

Devver

Pixelated

Ik zat even te kijken naar dat window.createRequest() hetgeen me niet bekend voorkwam. Dat blijkt de manier te zijn om een request te generen in IceBrowser; lijkt me niet echt een common browser en het is ueberhaupt te hopen dat de makers dat ook aanpassen aan de 'standaard' (XMLHttpRequest wordt overigens ook echt gestandaardiseerd door w3c).

Conditional Compilation is leuk maar over het algemeen onnodig; persoonlijk gebruik ik nog steeds deze functie zodat ik in IE ook gewoon op dezelfde manier als in andere browser een XMLHttpRequest object kan instantieren:

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
if (!window.XMLHttpRequest)
{
    window.XMLHttpRequest = function()
    {
        var types = [
            'Microsoft.XMLHTTP',
            'MSXML2.XMLHTTP.5.0',
            'MSXML2.XMLHTTP.4.0',
            'MSXML2.XMLHTTP.3.0',
            'MSXML2.XMLHTTP'
        ];

        for (var i = 0; i < types.length; i++)
        {
            try
            {
                return new ActiveXObject(types[i]);
            }
            catch(e) {}
        }

        return undefined;
    }
}

Intentionally left blank


  • BHR
  • Registratie: Februari 2002
  • Laatst online: 19-02 16:26

BHR

Volgens mij gebruik je de Prototype lib, of niet? Dan kan je dit eens proberen
JavaScript:
1
2
3
4
5
6
7
new Ajax.Request(url, 
{
parameters:'thisvar=true&thatvar=Howdy', 
onSuccess:handlerFunc, 
onFailure:errFunc,
options:{asynchronous: false}
});

No amount of key presses will shut off the Random Bug Generator


  • crisp
  • Registratie: Februari 2000
  • Laatst online: 20:34

crisp

Devver

Pixelated

Dan genereerd prototype nog steeds een asynchroon request; dit is de juiste manier:
JavaScript:
1
2
3
4
5
6
7
8
new Ajax.Request(url, 
{
    method: 'GET',
    parameters: 'thisvar=true&thatvar=Howdy', 
    asynchronous: false,
    onSuccess: myHandler, 
    onFailure: myError
});

echter wordt dan de callback functie niet meer aangeroepen hetgeen mij gewoon een bug/tekortkoming lijkt van prototype :P

Intentionally left blank


  • b19a
  • Registratie: September 2002
  • Niet online
Je kunt de onSuccess en onFailure ook gewoon weglaten, prototype zal hierover niet op z'n bek gaan. Dit komt omdat (voor asynchrone requests) de default actie is een lege functie die je eventueel kunt overschrijven met je eigen callback.

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 20:34

crisp

Devver

Pixelated

BoukeHaarsma schreef op maandag 08 mei 2006 @ 22:28:
Je kunt de onSuccess en onFailure ook gewoon weglaten, prototype zal hierover niet op z'n bek gaan. Dit komt omdat (voor asynchrone requests) de default actie is een lege functie die je eventueel kunt overschrijven met je eigen callback.
Er wordt door prototype helemaal geen callback aangeroepen bij een synchroon request hetgeen gewoon een bug is. Dat is tevens het nadeel van dergelijke libraries; de mensen die ze gebruiken hebben doorgaans te weinig kennis om dat soort problemen op te lossen (er schort wel meer aan de prototype library) en mensen die wel over genoeg kennis beschikken hebben doorgaans geen behoefte aan dergelijke libraries ;)

Intentionally left blank


  • b19a
  • Registratie: September 2002
  • Niet online
crisp schreef op maandag 08 mei 2006 @ 22:54:
[...]

Er wordt door prototype helemaal geen callback aangeroepen bij een synchroon request hetgeen gewoon een bug is. Dat is tevens het nadeel van dergelijke libraries; de mensen die ze gebruiken hebben doorgaans te weinig kennis om dat soort problemen op te lossen (er schort wel meer aan de prototype library) en mensen die wel over genoeg kennis beschikken hebben doorgaans geen behoefte aan dergelijke libraries ;)
We gaan nu misschien te ver off-topic, maar ik ben zeker wel benieuwd naar je mening hierover. Ikzelf gebruik de prototype library met plezier om het programmeren van javascript leuker te maken. Ik wil mezelf niet te druk maken over basale dingen die niet kunnen in javascript (Array.push en zulk soort). Ik zie mezelf niet als iemand die geen verstand zou hebben van javascript. Waarom zie jij af van het gebruik van een library?
Ik moet je toegeven dat de documentatie van prototype wel wat gebrekkig is, maar je kunt je voorstellen dat die callback niet geheel logisch zou zijn bij een synchrone request. Je wilt daar gewoon verder met je logica, en niet met callbacks extra functies aanroepen. Wat schort er nog meer aan de prototype library?

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 20:34

crisp

Devver

Pixelated

BoukeHaarsma schreef op maandag 08 mei 2006 @ 23:14:
[...]

We gaan nu misschien te ver off-topic, maar ik ben zeker wel benieuwd naar je mening hierover. Ikzelf gebruik de prototype library met plezier om het programmeren van javascript leuker te maken. Ik wil mezelf niet te druk maken over basale dingen die niet kunnen in javascript (Array.push en zulk soort).
Het Array object ondersteund native gewoon de push() method (af javascript 1.2 of 1.3 al, enkel IE5.0 kent het niet) :?
Ik zie mezelf niet als iemand die geen verstand zou hebben van javascript. Waarom zie jij af van het gebruik van een library?
Omdat in de tijd die ik nodig heb om een dergelijke library helemaal te doorgronden ik het zelf al geprogrammeerd heb en vaak op een betere manier of in ieder geval minder bloated dan dat de library het zelf doet. Dat plus het feit dat ik al vrij snel knelpunten zie in dergelijke libraries wat het gebruik ervan dus een sub-optimale oplossing maakt.
Ik moet je toegeven dat de documentatie van prototype wel wat gebrekkig is, maar je kunt je voorstellen dat die callback niet geheel logisch zou zijn bij een synchrone request. Je wilt daar gewoon verder met je logica, en niet met callbacks extra functies aanroepen.
Ik neem aan dat je toch graag iets zou willen doen met de responseText of responseXML - ook bij een synchroon request :?
Wat schort er nog meer aan de prototype library?
Request method in lowercase (RFC violation), niet javascript strict compliant (ambiguiteiten door toewijzingen te doen binnen vergelijkingen, functies die niet altijd een returnvalue hebben) en als ik echt de code in zou duiken dan vind ik zo nog wel een flink aantal zaken die beter kunnen.
Sowieso, een library waarin de meest gebruikte functies non-descriptive namen hebben als $() en $$() neem ik niet serieus :P

Het is zeker niet allemaal brandhout though, zelfs ik kan er nog wel eens ideeën van opdoen, maar het is gewoon niet mijn ding.

[ Voor 4% gewijzigd door crisp op 08-05-2006 23:32 ]

Intentionally left blank


  • b19a
  • Registratie: September 2002
  • Niet online
crisp schreef op maandag 08 mei 2006 @ 23:28:
Het Array object ondersteund native gewoon de push() method (af javascript 1.2 of 1.3 al, enkel IE5.0 kent het niet) :?
Het was een voorbeeld uit m'n hoofd, maar er zijn talloze extratjes die je krijgt met prototype.
Omdat in de tijd die ik nodig heb om een dergelijke library helemaal te doorgronden ik het zelf al geprogrammeerd heb en vaak op een betere manier of in ieder geval minder bloated dan dat de library het zelf doet. Dat plus het feit dat ik al vrij snel knelpunten zie in dergelijke libraries wat het gebruik ervan dus een sub-optimale oplossing maakt.
Ook zullen aan jouw implementaties gaatjes zitten, dus waarom zou je dure moeite stoppen in iets wat al helemaal uitgedacht is voor je?
Ik neem aan dat je toch graag iets zou willen doen met de responseText of responseXML - ook bij een synchroon request :?
JavaScript:
1
2
var request=new Ajax.Request({...});
response=request.transport.responseText;
Ik zie het probleem niet zo?
Request method in lowercase (RFC violation), niet javascript strict compliant (ambiguiteiten door toewijzingen te doen binnen vergelijkingen, functies die niet altijd een returnvalue hebben) en als ik echt de code in zou duiken dan vind ik zo nog wel een flink aantal zaken die beter kunnen.
Sowieso, een library waarin de meest gebruikte functies non-descriptive namen hebben als $() en $$() neem ik niet serieus :P
Ok RFC violations geloof ik je wel op en zal dan niet zo netjes zijn van de programmeurs. Een fuctie als $() is een helper om het programmeren te vereenvoudigen... het geeft je heel eenvoudig het element met het opgegeven ID.
Het is zeker niet allemaal brandhout though, zelfs ik kan er nog wel eens ideeën van opdoen, maar het is gewoon niet mijn ding.
Ieder z'n ding natuurlijk :).

[ Voor 1% gewijzigd door b19a op 09-05-2006 00:04 . Reden: enterts verwijderd ]


  • crisp
  • Registratie: Februari 2000
  • Laatst online: 20:34

crisp

Devver

Pixelated

BoukeHaarsma schreef op dinsdag 09 mei 2006 @ 00:03:
[...]
Het was een voorbeeld uit m'n hoofd, maar er zijn talloze extratjes die je krijgt met prototype.
Maar heb je die ook nodig of download je bezoeker voor niets 48KB aan script? ;)
[...]

Ook zullen aan jouw implementaties gaatjes zitten, dus waarom zou je dure moeite stoppen in iets wat al helemaal uitgedacht is voor je?
Mwa, in mijn eigen implementaties zal ik de gaatjes eerder kunnen vinden en fixen dan in andermans code...
[...]
JavaScript:
1
2
var request=new Ajax.Request({...});
response=request.transport.responseText;
Ik zie het probleem niet zo?
Ik wel; het is redelijk triviaal om ook een callback functie aan te roepen bij een synchroon request, dus waarom prototype daarin niet voorziet is mij een raadsel...
[...]
Ok RFC violations geloof ik je wel op en zal dan niet zo netjes zijn van de programmeurs. Een fuctie als $() is een helper om het programmeren te vereenvoudigen... het geeft je heel eenvoudig het element met het opgegeven ID.
Daarmee is het ook meteen de meest nutteloze functie in prototype - hooguit nuttig voor luie programmeurs die document.getElementById niet in 1x goed kunnen typen :P
Nu ik erover nadenk is de functienaam misschien toch wel goed gekozen, $ staat misschien wel voor 'duur' aangezien DOM lookups niet bepaald de goedkoopste acties zijn performance-wise. Het zou een nuttige functie zijn als er ook een caching-mechanisme in zou zitten ;)
[...]
Ieder z'n ding natuurlijk :).
Ik ben gewoon beter :P

Intentionally left blank

Pagina: 1