Forståelse af javascript

Tags:    javascript

Hejsa

Har jeg forstået det korrekt at javascript afvikles asynkront?

Mit problem er at jeg har en metode der skal opbygge nogle data til brug for at generere et chart for disse data.
På nuværende tidspunkt bruger jeg en alert til at vise jeg har sat den globale variabel og dermed "forsinker" eksekvering af det videre javascript.

Jeg har 2 metoder:
- GetJSONData
- DrawChart

GetJSON data henter data og sætter dem i en global variabel jeg skal bruge senere til DrawChart.

DrawChart kaldes automatisk som siden læses og mit problem er at selvom jeg kalder GetJSONData som det første, inden jeg begynder at gøre brug af den globale variabel så er det som om det kald til GetJSONData eksekveres i sin egen tråd og videre fortolkning af mit Javascript (DrawChart) fortsætter.

Hvad er best practice til sådanne situationer?
Jeg er vant til at jeg har en metode som afvikles for så at returnere før min første metode fortsætter.



8 svar postet i denne tråd vises herunder
0 indlæg har modtaget i alt 0 karma
Sorter efter stemmer Sorter efter dato
Nej, selve JavaScript koden afvikles synkront, men flere forskellige aspekter af JavaScript afvikles asynkront, fx XHR, WebWorkers etc. Din metode "GetJSONData" lyder som om, den henter data fra en server, hvis den benytter sig af AJAX til dette, så er det formentlig en asynkron process.

I JavaScript er såkaldte "callback" funktioner blevet en meget populær løsning på asynkrone kald. Ideen er at du kalder funktionen "GetJSONData" med en funktion som argument, der så bliver kaldt når din data er blevet hentet.

Pseudo:
Fold kodeboks ind/udJScript kode 


Egentlig er den funktion du tildeler "xhr.onreadystatechange" også en callback funktion, der bliver kaldt hver gang der er nye informationer omkring dit serverkald.



Indlæg senest redigeret d. 07.11.2012 22:55 af Bruger #11328
@Jakob
Tak for hurtigt svar.

Processen er:
DrawChart() kaldes fra en script-block.
Denne kalder så GetJSONData() som bruger jQuery til at lave et ajax-kald til min server for at få nogle JSON data. Hertil bruger jeg
Fold kodeboks ind/udJScript kode 

Efter min GetJSONData()-kald bruger jeg værdien af den globale variabel (hvis den er sat).

Men forstår jeg det korrekt at fordi jQuery's callback metode sættes så laves det asynkront og derfor sættes getJSON-metoden igang og fortsætter asynkront og derfor vender tilbage til min DrawChart() inden det asynkrone kald til callback metoden har sat min globale variabel?

Og hvad er best practice med hensyn til sådanne "udfordringer"? Hvordan plejer man at lave dette bedst?



Du kan se det sådan her...jeg har sat "linjenumre" ind so viser kronologien:
Fold kodeboks ind/udJScript kode 


Så sidste linje bliver udført før dataene er hentet...det er det asynkrone.



Du skal dele din logik op. Jeg ville fx omdøbe din funktion "drawChart" til noget andet, mere sigende fx: "beginDrawChart". Herefter ville min callchain se sådan her ud:

beginDrawChart() -> getJSONData() -> drawChart(data);

Du kalder altså selve "tegne" funktionen, der benytter din data, fra callback'et i getJSONData metoden:

Fold kodeboks ind/udJScript kode 


Et problem du kan støde ind i er meget dybe "nested call trees", i det du nogen gange vil opleve en hulens masse callback funktioner inden i hinanden. Der er dog mange måder at løse dette på, og de er blot en Google søgning væk.

edit: PS:
Det er generelt best-practice kodestil, at navngive normale funktioner med camelCase (altså lille start bogstav). Normalt forbeholder man funktioner med stort begyndelsesbogstav til "class" constructorer.



Indlæg senest redigeret d. 08.11.2012 10:36 af Bruger #11328
Man kan faktisk chain det med deferred ... det er lidt kompliceret, men super sejt :)

Fold kodeboks ind/udJScript kode 




Indlæg senest redigeret d. 08.11.2012 12:45 af Bruger #17081
Så skal init() se således ud:
Fold kodeboks ind/udJScript kode 


...altså ikke semikolon efter 'done(drawChart)'



yes .. det var en fastetejl :)
Teknisk set burde man nok også pakke det hele lidt mere ind:

Fold kodeboks ind/udJScript kode 





Indlæg senest redigeret d. 08.11.2012 12:51 af Bruger #17081
Du skal dele din logik op. Jeg ville fx omdøbe din funktion "drawChart" til noget andet, mere sigende fx: "beginDrawChart". Herefter ville min callchain se sådan her ud:

beginDrawChart() -> getJSONData() -> drawChart(data);

Du kalder altså selve "tegne" funktionen, der benytter din data, fra callback'et i getJSONData metoden:

Fold kodeboks ind/udJScript kode 


Et problem du kan støde ind i er meget dybe "nested call trees", i det du nogen gange vil opleve en hulens masse callback funktioner inden i hinanden. Der er dog mange måder at løse dette på, og de er blot en Google søgning væk.

edit: PS:
Det er generelt best-practice kodestil, at navngive normale funktioner med camelCase (altså lille start bogstav). Normalt forbeholder man funktioner med stort begyndelsesbogstav til "class" constructorer.


Tak Jakob

Mit problem er at jeg bruger Google charts i denne forbindelse.
Det eksempel jeg har bygget videre på har en ren scripts blok uden metode til at initialisere tegningen af dette chart, og i denne forbindelse jeg så skal kalde mit jQuery AJAX for at få data til at kunne bruge for at kunne fylde data i rigtigt format ind for så at tegne mit chart.
Se gerne mere her: http://jsfiddle.net/WedEF/4/

Som du kan se så er data nu indskrevet i javascriptet, men skal have det lavet således at jeg kan modtage mine JSON data (fra jQuery AJAX kald) til at lave samme trick - bare dynamisk med de hentede data.

Jeg er klar over at der findes masser af løsninger derude, men der findes også enormt mange forkerte og dårlige som jeg lidt håbede på i ville kunne skære igennem.
Jeg har intet imod at Google og læse, men et fingerpeg om retning hjælper lidt så jeg ikke bare læser 7 forskellige måder og tænker ja de er smarte så må jeg bare prøve dem alle sammen af før jeg forstår hvad der er smart og dumt ved hver og håbe på jeg rammer alt det dumme i mine forsøg :)
Der er enormt kloge folk herinde som jeg håbede på kunne give lidt ide om hvad jeg skal søge efter eller forklare lidt hvad er godt / skidt og hvorfor den ene metode at gøre tingene på er bedre end en anden.

Man kan faktisk chain det med deferred ... det er lidt kompliceret, men super sejt :)

Fold kodeboks ind/udJScript kode 


Kan du eller nogle af de andre hjælpe med at forklare defered? At man kan sætte metoder i forlængelse af hinanden?



Indlæg senest redigeret d. 08.11.2012 13:13 af Bruger #17215
t