Verständnis: XHR, Closures und Garbage Collector
![](/uploads/default_avatar/thumb/missing.png)
- javascript
Liebe JS-Spezialisten,
weil ich es nicht besser wusste (und noch immer nicht besser weiß), habe ich in meinen Scripts für AJAX-Funktionalitäten immer ein für die Applikation festes XHR-Objekt definiert. Das sah in etwa so aus:
var MyApp = {
xhr: {},
init: function () {
...
this.xhr = this.createXHR();
},
createXHR: function () {
... // Code wie [link:http://de.wikipedia.org/wiki/Xmlhttprequest#Codebeispiele_.28JavaScript.29@title=Wikipedia]
}
}
Bisher hatte ich das Gefühl (mir fehlen hier die Fakten, daher dieses Posting), dass ich ein XHR-Objekt "irgendwie speichern" muss, da es ansonsten nach Beenden der Funktion dem Garbage Collector zum Opfer fällt. Aber das wäre doch blanker Unsinn, der den Sinn dieses Objekts überhaupt in Frage stellen würde, oder nicht? Immerhin soll das Objekt von sich aus tätig werden und bei Änderungen seiner readystate-Eigenschaft mit passenden Events Dinge tun.
Ist ein XHR-Objekt so etwas wie eine besondere Form der Closure, also eines Variableninhalts, der "irgendwie überlebt"? Wann schlägt denn der GC zu, falls ich das XHR-Objekt in einer lokalen Variable speichere, um am Ende der Funktion diese dann wieder zu "vergessen"?
Ist es möglich, dass ich bei meiner obigen Vorgehensweise die Response eines XHR-Objektes "zerstöre", indem ich das Objekt verändere, weil ich einen neuen Request absetzen will? Wäre es in diesem Fall besser und einfacher, das dort abgelegte XHR-Objekt einfach durch ein neues zu überschreiben, damit das alte im Hintergrund fertig werden kann?
Wer kann mich da über die Interna des Browsers aufklären?
Liebe Grüße,
Felix Riesterer.
Hallo,
Bisher hatte ich das Gefühl (mir fehlen hier die Fakten, daher dieses Posting), dass ich ein XHR-Objekt "irgendwie speichern" muss, da es ansonsten nach Beenden der Funktion dem Garbage Collector zum Opfer fällt.
Du musst es nicht zwangsläufig speichern. Der readystatechange-Handler wird auch gefeuert, wenn keine Variable/keine Eigenschaft mehr auf das Objekt verweist. Darin hat man über this Zugriff auf das XHR-Objekt, braucht also keine äußere Variable.
Ist ein XHR-Objekt so etwas wie eine besondere Form der Closure, also eines Variableninhalts, der "irgendwie überlebt"?
Es hat wohl eher einen Flag, sodass es der GC nicht abräumt, solange es noch arbeitet und der Handler nicht im finalen State ausgeführt wurde. Dasselbe gilt für den daran klebenden Handler. Diese Vorgehensweise ist wohl mit setTimeout vergleichbar. Die verzögert ausgeführte Funktion wird intern auch so gespeichert, dass der GC sie vor ihrer Ausführung nicht löscht.
Wann schlägt denn der GC zu, falls ich das XHR-Objekt in einer lokalen Variable speichere, um am Ende der Funktion diese dann wieder zu "vergessen"?
Nein. Dann wird zwar die Variable zerstört und für den Moment existiert keine Referenz mehr auf das Objekt, aber im irgendwann später feuernden readystatechange-Handler hast du wieder Zugriff auf das XHR-Objekt.
Ist es möglich, dass ich bei meiner obigen Vorgehensweise die Response eines XHR-Objektes "zerstöre", indem ich das Objekt verändere, weil ich einen neuen Request absetzen will? Wäre es in diesem Fall besser und einfacher, das dort abgelegte XHR-Objekt einfach durch ein neues zu überschreiben, damit das alte im Hintergrund fertig werden kann?
Das Wiederverwenden von XHR-Objekten ist möglich, google mal nach »reuse xmlhttprequest«. Heutzutage dürfe es aber kein Problem sein, einfach ein neues anzulegen.
In dem Fall, wo du die Variable/die Eigenschaft mit einem neuen überschreibst, musst du das alte abbrechen, sonst feuert der Handler für das alte ggf. trotzdem.
Mathias
Lieber Mathias,
herzlichen Dank für die Klarstellungen. Das bringt mich enorm weiter. Ich werde von nun an XHR-Objekte nur noch als lokale Variablen nutzen, da ich nun verstanden habe, dass sie wie setTimeout "einfach funktionieren" und ich mir um Referenzen auf XHR-Objekte wegen Lebenserwartung und so keine Gedanken mehr machen muss.
Liebe Grüße,
Felix Riesterer.