2012-12-24 1 views
9

Il mio background è in linguaggi orientati agli oggetti compilati tradizionali come la programmazione C++ e .NET, e ora sto dilettandomi in un po 'di JavaScript per un nuovo progetto. Mi sono dilettato con AJAX e mi sono imbattuto in un aspetto confuso su come gli oggetti sono gestiti dal browser.In che modo gli oggetti xmlhttprequest vengono creati, uniti e distrutti in Javascript

[Modifica # 2] - Variazione script contenuti attivi

Ho una pagina di pratica con tre pulsanti che ogni aggiornamento di un <textarea> utilizzando XMLHttpRequest oggetti:

  1. Button 1 aggiornamenti TextArea1 con testo contenuto da slowtime.php
  2. Pulsante 2 aggiornamenti TextArea2 con contenuto di testo da slowtime.php
  3. Pulsante 3 aggiornamenti TextArea3 con contenuti di testo da fasttime.php

Dove slowtime.php e fasttime.php sono semplici script che restituiscono una pagina di testo/HTML con due timestamp: uno quando la pagina si carica, uno dopo un po 'di tempo è trascorso.

Ciascuno dei pulsanti funziona correttamente se cliccato uno alla volta. Se faccio clic sul pulsante 2 e poi sul pulsante 3 prima che venga completata la prima richiesta, gli aggiornamenti funzionano ancora come previsto.

Se faccio clic sul pulsante 1 e poi sul pulsante 2 prima che la prima richiesta sia completa, TextArea1 e TextArea2 ricevono i valori corretti; tuttavia, le chiamate all'evento onreadystatechange si verificano contemporaneamente, ovvero la prima risposta in ritardo e viene elaborata solo quando arriva la seconda.

codice di esempio

Sito

<!DOCTYPE html> 
<html> 
<head> 
<script> 
function loadXMLDoc(url,target) 
{ 
var xmlhttp; 
xmlhttp=new XMLHttpRequest(); 

xmlhttp.onreadystatechange=function() 
    { 
    if (xmlhttp.readyState==4 && xmlhttp.status==200) 
    { 
    document.getElementById(target).value=xmlhttp.responseText; 
    } 
    } 
xmlhttp.open("POST",url,true); 
xmlhttp.send(); 
} 
</script> 
</head> 

<body> 
<form> 

<input type="button" value="Button 1" onClick="loadXMLDoc('slowtime.php','TextArea1')"/> 
<input type="button" value="Button 2" onClick="loadXMLDoc('slowtime.php','TextArea2')"/> 
<input type="button" value="Button 3" onClick="loadXMLDoc('fasttime.php','TextArea3')"/> 

<div><textarea id="TextArea1"></textarea></div> 
<div><textarea id="TextArea2"></textarea></div> 
<div><textarea id="TextArea3"></textarea></div> 

</form> 
</body> 
</html> 

codice PHP (slowtime.php)

<?php 
    echo date('h:i:s') . "\n"; 
    sleep(5); 
    echo date('h:i:s') . "\n"; 
?> 

Domande [Revised]

In che modo il browser gestisce gli oggetti XMLHttpRequest? Premendo i pulsanti 2 e 3 si indica che ogni pressione istanzia un nuovo oggetto e ognuno di questi ha gestori di eventi indipendenti. Se gli oggetti vivono oltre la chiamata di funzione iniziale (dal momento che i loro gestori di eventi sopravvivono) quando vengono cancellati dalla memoria/distrutti?

Se il XMLHttpRequests sono oggetti separati, come fa l'invio di una seconda richiesta allo stesso URL influenzare i tempi di risposta del primo? Questo potrebbe essere un problema lato server?

+0

Nella 'funzione xmlhttp.onreadystatechange', si dovrebbe forse usare' this.responseText' invece di 'xmlhttp.responseText'? –

+1

@ JoshuaD.Boyd che non dovrebbe fare altro, come la variabile 'xmlhttp' è in un ambito locale all'interno del' loadXMLDoc'. – Tyilo

+0

cambiare tutti i riferimenti a 'xmlhttp' a' this' nella funzione 'onreadystatechange' funziona anche, e produce anche lo stesso comportamento – nicholas

risposta

2

contesto a XMLHttpRequest non viene mai eliminato a meno che l'eliminazione non venga richiamata esplicitamente sull'oggetto. In questo caso: xmlhttp. Dovresti davvero tracciare quel var in qualche modo e ripulirlo se vuoi che la tua applicazione sia snella e pulita. Javascript è stato originariamente progettato per le pagine Web, quindi tende a lasciar correre le cose a meno che non lo si impedisca da solo.

In caso contrario, è possibile che una volta che l'oggetto non è più utilizzabile da altre funzioni o non abbia ancora richiamato, il garbage collector del browser eliminerà l'oggetto.

Per quanto riguarda il problema con gli eventi che accadono contemporaneamente, non posso riprodurre il problema me stesso, che mi lascia a credere di avere un problema con la configurazione di PHP. È possibile che il tuo server non consenta l'esecuzione contemporanea di più script?

Ecco il vostro esempio sul mio server, con un paio di lievi modifiche: http://www.seijinohki.net/test.php

+0

Grazie per aver postato il codice su un altro server di test. Quando provo il tuo sito in Chrome o Safari, ottengo gli stessi risultati di rambo, sopra - entrambe le aree di testo hanno lo stesso valore. Nel frattempo, Firefox, IE9 e Silk no. La tua pagina non funziona affatto nel browser mobile Maxthon. – nicholas

+0

ben dopo molto tempo, accetto questa come risposta poiché affronta direttamente il contesto delle richieste.un'interessante discussione, e va a mostrare, almeno attualmente, che lo sviluppo web/browser/ecc. sono ancora tutt'altro che uniformi nel modo in cui eseguono gli script. – nicholas

1

Questo è un problema di browser.

  • Chrome 23 & 26 si comportano in questo modo.
  • Opera 12 doesnt
  • IE 9 pretende molto
  • Firefox 17 doesnt

Se si fanno i URL unici, ad esempio slowtime.php?1 e slowtime.php?2 poi Chrome non è più si comporta in questo modo.

BTW nel mio test Chrome si aggiorna entrambe le aree di testo con gli stessi valori - i valori della prima richiesta. e entrambi si aggiornano quando finisce la prima richiesta, non quando il secondo finisce. questo è sicuramente un bug perché è semplicemente sbagliato. Ho verificato tramite i log del server web che la seconda richiesta non viene mai inviata.

+0

Quando provo con Chrome o Safari sul server di kokorohakai, vedo lo stesso risultati che ottieni - entrambe le aree di testo ottengono lo stesso valore e sono sincronizzate con la prima richiesta. Nel frattempo sul mio server di test (localhost), ottengo due valori diversi, cronometrati con il secondo. Questo mi porta a credere che la risposta sia molto complicata, in effetti, e sia basata sul comportamento di browser e server. – nicholas

+0

@nicholas il registro del server locale indica due richieste? tuttavia, il fatto che Chrome abbia inviato solo una richiesta nel mio test indica un bug (o una caratteristica strana). – goat