Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 15

Discussione: [ajax] poco asincrono

  1. #1
    Utente di HTML.it L'avatar di supermac
    Registrato dal
    Jun 2001
    Messaggi
    1,881

    [ajax] poco asincrono

    ciao a tutti
    ho bisogno che mi spieghiate una cosa:
    io mi sono fatto una funzione in JS alla quale passo due parametri, il primo è la pagina asp che deve essere eseguita lato server e che deve produrre il risultato, il secondo è l'ID di un div nel quale il risultato dovrà essere riportato.
    Con questo giochetto, per fare un esempio, sull'onclick di un bottone posso modificare il contenuto di diverse zone della mia pagina con una scrittura tipo
    onclick='funzione("pag1.asp","div1");funzione("pag 2.asp","div2");funzione("pag3.asp","div3");'

    Il problema è che l'esecuzione delle tre pagine asp non avviene, come volevo/speravo contemporaneamente, ma avviene sequenzialmente ossia prima di vedere aggiornato il div3 bisogna che si aggiornino in cascata prima il div1 e il div2.

    Come posso ovviare (se è possibile ovviare)?
    W la Ferari effetrenavenave!
    il computer è un somaro veloce! (neanche tanto ndr)

  2. #2
    Il fatto che Ajax sia asincrono non ovvia interamente al fatto che la esecuzione dello script si affida a ordini procedurali: se i tuoi ajax sono invocati in fila 1 2 e 3, nulla impedisce a un server "alert e responsive" di ritornare le sue risposte proprio nell' ordine in cui sono state emesse

    E' in realtà questo lo stato di cose ottimale, poichè della asincronicità di Ajax ci si può avvalere solo se un server è lento o se uno dei task inviati via ajax richiede qualche secondo in piu degli altri (ad esempio perchè fa lo scan di una tabella nel db, magari non indicizzata).

    Ma i processori sono veloci, e molti ajax si limitano a prelevare piccoli dati da tabelle di modesta entità e tutte diligentemente indicizzate: ho l'impressione che tu ti stia inavvertitamente lamentando del fatto che il tuo server è troppo veloce :-)

    Ps.: quando ottieni la risposta da Ajax dal server, torni nel reame Javascript: se arrivano 3 risposte contemporanee, Javascript le mette in sequenza procedurale comunque (quella in cui sono arrivate, e comunque le allinea perchè javascript non va in multiasking).
    La perfetta contemporaneità non esiste (nemmeno al cinema, dove le immagini sembrano continue ma non lo sono...): la potrai avere solo con i cosiddetti computer quantici, ma temo sarà roba per i nostri nipoti...

  3. #3
    Utente di HTML.it L'avatar di supermac
    Registrato dal
    Jun 2001
    Messaggi
    1,881
    Risposta chiarissima.

    L'effetto che rilevo purtroppo è che sembra che la terza funzione attenda il termine delle prime due prima di essere lanciata, cioè la sequenzialità non si avverte al momento del "rendering", diciamo così, ma sembra essere proprio in fase di lancio.
    Considera che poi io non sono una cima nè in JS nè in ASP, chiedevo qui infatti se avevo sbagliato qualcosa (che ne so, se magari la sequenzialità si avvertiva per il fatto che è sempre la stessa funzione che viene lanciata -sempre stesso oggetto XMLHTTP- e quindi poteva essere aggirata usando tre funzioni "gemelle" ma diverse... sto buttando idee strampalate me ne rendo conto :-) )

    Domande specifica per il mio esempio: se arrivano tre risposte nell'ordine diverso da quello in cui sono state lanciate (succede facilmente nel caso di tre pagine asp che elaborano masse di dati diversi), vengono "renderizzate" nell'ordine di arrivo o viene comunque mantenuto l'ordine di lancio?
    W la Ferari effetrenavenave!
    il computer è un somaro veloce! (neanche tanto ndr)

  4. #4
    In quello di arrivo.

    La cosa sta così:

    1) LANCIO AJAX - Javascript lo lancia in ordine procedurale, ma gli script non debbono attendere la fine della esecuzione (la risposta) dello script avviato per avviare altri script (siamo dunque asincroni per questo).

    2) SERVER: gestisce la risposta e manda una eco nell' ordine che crede.

    3) RITORNO AD AJAX: siamo di nuovo dentro Javascript, cioè procedurali; non appena una eco arriva, Javascript la esegue. Nel mentre che soddisfa, a velocità del processore del client, la risposta arrivata, la mia logica (poichè non ho documentazione alla mano) mi dice che Javascript sospende tutto il resto in attesa di completare il task arrivato.

    Il clock del client lancia ajax ad (1) in ordine procedurale, e poi se ne "disinteressa". Ma quando l'eco torna, non vedo come potrebbe sottrarsi alla sincronicità del clock del client: non è più un "messaggio in bottiglia" lanciato nell' etere verso il server, è proprio un task tornato a javascript.
    Potrei sbagliarmi ovviamente, ma mi pare una deduzione abbastanza convincente.

    ciao

  5. #5
    La soluzione più ovvia sarebbe quella di fare una sola chiamata al server che ti restituisca tutti i valori che ti servono.
    Se per qualche motivo non fosse possibile puoi sempre impostare un qualche flag booleano per verificare che anche le altre due richieste siano state completate...

    Così aggiorni i div contemporaneamente dopo la fine di tutte le richieste

  6. #6
    nick appropriato a quanto pare ... o forse sono io a non aver capito ...

    2 o più chiamate ajax, se effettuate dalla stessa funzione, partono con l'ordine di chiamata della funzione (procedurale) ma se asincrone, termine non coniato a caso, non c'è assolutamente alcun vincolo/garanzia che le risposte arrivino in sequenza ... sarebbe come dire che se scrivessi:
    codice:
    setTimeout(function(){alert("1")}, 2000);
    setTimeout(function(){alert("2")}, 25);
    la funzione con alert("2") non venisse eseguita fino a che quellla con timeout da 2000 "non abbia finito", un pò una castroneria poichè è vero che JavaScript non è multi thread (e non è con Ajax o questo esempio che lo si capisce) ma è altrettanto vero che il clock, quando le chiamate sono asincrone, accoda la prima che arriva e la esegue appena può.

    L'esempio di quanto detto è su una banalissima deadlock mostrata in questo mio post, dove è evidente che la sincronia di esecuzione non permette ad una chiamata asincrona di essere eseguita prima che la successione di operazioni procedurali sia ultimata ... esempio spiegato con tanto di codice anche nella guida Ajax ...

    per concludere, avrebbe senso dire che 1 e 2 sono in sequenza in un caso come questo:
    setTimeout(function(){alert("1")}, 25);
    setTimeout(function(){alert("2")}, 25);
    dove si sa che i tempi di risposta sono esattamente identici ma questo non è il caso di Ajax poichè il server (e mettiamoci anche la connessione in mezzo) può rispondere come meglio crede e raramente avrà gli stessi tempi su operazioni (pagine) differenti a meno che non ci siano vincoli ben noti ed impostati per cui una sessione utente non possa concludere operazione 2 finchè operazione 1 non è stata ultimata.

    Questo vincolo è tipico della continuation ... che personalmente comincio ad odiare, ma tale procedura non è solitamente presente/impostata nei comuni host che usiamo tutti i giorni.

    In soldoni, se dalla stessa window fai due chiamate e lo script crea una richiesta per ognuna di queste ma le stesse vengono processate "in procedurale" significa che hai vincoli di configurazione nel server/servizio che stai utilizzando, a volte sono vincoli giustificati (continuation) a volte sono impostazioni fatte male (o perchè no, lo script che usi che accoda in queue le requestes), non so quale sia il tuo caso


    [edit]
    Originariamente inviato da Mega69
    La soluzione più ovvia sarebbe quella di fare una sola chiamata al server che ti restituisca tutti i valori che ti servono.
    concordo in pieno ... soprattutto quando si accorpano 3 chiamate al server in un'unica callback, di solito c'è qualcosa che non va a livello di progettazione client/server
    Formaldehyde a new Ajax PHP Zero Config Error Debugger

    WebReflection @WebReflection

  7. #7
    per caso state pensando a me ?
    Farmacia di Jarno - le mie pillole: Cookie [#780810], Dom4Php4 [#1123236], Fade [#1139489], getCssProperty [#1152911]
    Inchinatevi difronte al Prof! Nacchio!

    A me pare che l'uomo vada avanti con la retromarcia

  8. #8
    Utente di HTML.it L'avatar di supermac
    Registrato dal
    Jun 2001
    Messaggi
    1,881
    forse se posto la funzione si capisce meglio:

    function chiama(par,nano2){
    var nano, voce, pagina
    var xmlHttp = null

    //qui decide se mettere il risultato in un oggetto di cui è noto l'ID o se scrivere direttamente
    function stateChanged() {
    if (xmlHttp.readyState==4 || xmlHttp.readyState=="complete") {
    if (xmlHttp.responseText=="sessionscaduta") {
    //alert("Sessione scaduta!");
    top.location.href="index.asp";
    }
    if (nano == "£") {
    voce = xmlHttp.responseText.split("|#");
    voci();
    } else{
    //alert("chiamato per esecuzione asp")
    document.getElementById(nano).innerHTML=xmlHttp.re sponseText ;
    voci()
    }
    }
    //document.getElementById("bodi").style.cursor="defa ult";
    //alert("inviato");
    }
    //questa serve a individuare l'oggetto xmlhttp più adatto
    function GetXmlHttpObject(handler)
    {
    var objXMLHttp=null
    try {
    objXMLHttp=new ActiveXObject("Msxml2.XMLHTTP")
    }
    catch(e) {
    try {
    objXMLHttp=new ActiveXObject("Microsoft.XMLHTTP")
    }
    catch(f){
    objXMLHttp=new XMLHttpRequest()
    }
    }
    return objXMLHttp
    }
    // questa l'ho fatta io: distribuisce nei vari oggetti i valori dell'array
    function voci(){
    try {
    for (i=0; i<voce.length; i++) {
    if (document.getElementById("id"+i)){
    document.getElementById("id"+i).innerHTML=voce[i];
    //} else {
    //alert("elemento id"+ i + " not found");
    }
    }
    } catch(y) {
    }
    }


    xmlHttp=GetXmlHttpObject();
    if (xmlHttp==null){
    alert ("Browser does not support HTTP Request");
    return
    }
    document.getElementById("bodi").style.cursor="wait ";
    var url=par;
    nano = nano2
    url=url+"&sid="+Math.random()
    xmlHttp.onreadystatechange=stateChanged;
    xmlHttp.open("GET",url,true);
    xmlHttp.send(null);
    document.getElementById("bodi").style.cursor="defa ult";
    }
    perdonate il pessimo codice, scritto pescando qua e là da altri codici!!! (ho già detto che sono un nerd in JS)
    Ho provato anche (senza successo) a cambiare il cursore del mouse durante l'esecuzione del codice sulle pagine asp (bodi è l'ID che ho dato al tag body).
    Quell' if (nano == "£") è lì perchè usavo la stessa funzione per comporre un array di valori da usare in altro loco... ignoratelo.

    Come già detto io uso chiamare la funzione chiama(a,b) in serie sul click di un bottone, in modo da poter aggiornare diversi div sparsi sulla mia pagina.
    Domanda: in questa funzione c'è qualcosa che renda le chiamate sequenziali (che cioè non possano essere processate "in simultanea" -l'ho messo tra virgolette apposta-)?
    Io avevo ipotizzato che utilizzando un unico oggetto xmlhttp questo non potesse essere impegnato da più richieste concorrenti... è sbagliato?
    grazie a tutti
    W la Ferari effetrenavenave!
    il computer è un somaro veloce! (neanche tanto ndr)

  9. #9
    Utente di HTML.it L'avatar di supermac
    Registrato dal
    Jun 2001
    Messaggi
    1,881
    questo silenzio mi fa pensare che sia sbagliato...
    helps?
    suggestions?
    thx
    W la Ferari effetrenavenave!
    il computer è un somaro veloce! (neanche tanto ndr)

  10. #10
    Utente di HTML.it L'avatar di pietro09
    Registrato dal
    Jan 2002
    Messaggi
    10,116
    Originariamente inviato da supermac
    questo silenzio mi fa pensare che sia sbagliato...
    helps?
    suggestions?
    thx
    è difficile rispondere quando la risposta non viene recepita. Prova a cambiare la logica:

    al posto di avere tre funzioni richiamate in successione:
    onclick='funzione("pag1.asp","div1");funzione("pag 2.asp","div2");funzione("pag3.asp","div3");'

    ne richiami una solo
    onclick='lancia_ajax();'


    in PSEUDOCODICE, lancia_ajax richiama una sola pagina server
    function lancia_ajax()
    {
    //lancio ajax richiamando UNA SOLA PAGINA SERVER
    ajax(url, parametri, onload);
    function onload()
    {
    var j.json recuperato dal server;

    $("div1").innerHTMO = j.div1;
    $("div2").innerHTMO = j.div2;
    $("div3").innerHTMO = j.div3;

    }
    }

    il resultato viene fornito dal server tramite una string json con tre campi, o con una stringa con tre campi separati da un delimitatore

    adesso disassemblo la stringa e la immetto nei tre div

    se vuoi si può continuare usando per esempio prototype o altro, altrimenti... ciao
    Pietro

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.