Visualizzazione dei risultati da 1 a 10 su 10
  1. #1
    Utente di HTML.it L'avatar di LuckySevenRoX
    Registrato dal
    Sep 2011
    residenza
    Foligno
    Messaggi
    361

    Ajax in ciclo for: rispettare le "precedenze"

    Salve, vorrei risolvere un piccolo problema che ho:

    un ciclo for prende in esame gli elementi di un array, e per ognuno di questi fa una richiesta AJAX a una pagina che restituisce N righe di testo.

    Il problema è che ovviamente se l'elemento 2 dell'array ha una risposta ajax più veloce rispetto al primo i risultati che avrò nella pagina non saranno ordinati come dovrebbero essere (e così via).

    Come posso risolvere questo problema? come posso fare in modo che le risposte ajax mi arrivino ordinate così come ho inviato le richieste?

    Grazie
    Ti rivedrò in un'altra vita…quando saremo tutti e due gatti...

  2. #2
    Utente di HTML.it
    Registrato dal
    Dec 2010
    Messaggi
    3,660
    fai richieste sincrone...

  3. #3
    Utente di HTML.it
    Registrato dal
    Jun 2007
    Messaggi
    74
    oppure posta un'esempio di codice...
    ..
    "Voi che avete gl'intelletti sani,mirate la dottrimna che s'asconde dietro il velame delli versi strani".

  4. #4
    Utente di HTML.it L'avatar di Xinod
    Registrato dal
    Sep 2000
    Messaggi
    13,649
    non puo' trovarsi in un ciclo

    nel success/error di ogni chiamata ajax incrementa un contatore e richiama la stessa funzione
    se il contatore raggiunge la lunghezza dell' array non procedere ulteriormente

  5. #5
    Frontend samurai L'avatar di fcaldera
    Registrato dal
    Feb 2003
    Messaggi
    12,924
    usando i deferred objects di jQuery (o analoga implementazione del pattern Promises/A) puoi concatenare in sequenza chiamate ajax asincrone
    Vuoi aiutare la riforestazione responsabile?

    Iscriviti a Ecologi e inizia a rimuovere la tua impronta ecologica (30 alberi extra usando il referral)

  6. #6
    io mi sono trovato bene con questo piccolo framework

    http://benalman.com/projects/jquery-...ueuing-plugin/

    nell'esempio si vede proprio come realizzare una coda di chiamate ajax asincrone

  7. #7
    Utente di HTML.it L'avatar di LuckySevenRoX
    Registrato dal
    Sep 2011
    residenza
    Foligno
    Messaggi
    361
    Grazie a tutti per le risposte, scusate il ritardo ma sono stato un pò fuori questi giorni e avevo momentaneamente abbandonato lo script che stavo facendo.

    Per ora la prova che ho fatta è stata solo quella con la proprietà async di ajax (jquery), che però mi da problemi.

    Se non setto async o lo imposto a true lo script funziona ma non rispetta l'ordine delle chiamate (giustamente).. se metto async a false non mi riporta nessun risultato e non capisco perchè.. devo settare qualche altra proprietà insieme ad async?
    Ti rivedrò in un'altra vita…quando saremo tutti e due gatti...

  8. #8
    Frontend samurai L'avatar di fcaldera
    Registrato dal
    Feb 2003
    Messaggi
    12,924
    non mi è chiaro però come vorresti gestire l'ouput di ritorno delle chiamate ajax

    semplifichiamo il problema e supponiamo tu abbia 3 chiamate ajax ad altrettanti script richiesti in quest'ordine

    script1.php - termina in 4 secondi e produce come output "a"
    script2.php - termina in 2 secondi e produce come output "b"
    script3.php - termina in 6 secondi e produce come output "c"

    hai due possibilità: invii tre richieste e poi

    1) aspetti che tutte le richieste terminino (cioè aspetti 6 secondi) e quindi visualizzi l'output ordinato (abc)

    oppure

    2) non appena è pronta la prima risposta (dopo 4 secondi e quindi nel frattempo è pronta anche la seconda) stampi "ab" e dopo altri due secondi vuoi stampare "c"

    ?
    Vuoi aiutare la riforestazione responsabile?

    Iscriviti a Ecologi e inizia a rimuovere la tua impronta ecologica (30 alberi extra usando il referral)

  9. #9
    Utente di HTML.it L'avatar di LuckySevenRoX
    Registrato dal
    Sep 2011
    residenza
    Foligno
    Messaggi
    361
    Originariamente inviato da fcaldera
    non mi è chiaro però come vorresti gestire l'ouput di ritorno delle chiamate ajax

    semplifichiamo il problema e supponiamo tu abbia 3 chiamate ajax ad altrettanti script richiesti in quest'ordine

    script1.php - termina in 4 secondi e produce come output "a"
    script2.php - termina in 2 secondi e produce come output "b"
    script3.php - termina in 6 secondi e produce come output "c"

    hai due possibilità: invii tre richieste e poi

    1) aspetti che tutte le richieste terminino (cioè aspetti 6 secondi) e quindi visualizzi l'output ordinato (abc)

    oppure

    2) non appena è pronta la prima risposta (dopo 4 secondi e quindi nel frattempo è pronta anche la seconda) stampi "ab" e dopo altri due secondi vuoi stampare "c"

    ?
    è indifferente, nel senso che posso anche aspettare di avere tutti e 3 i risultati e poi stampare
    Ti rivedrò in un'altra vita…quando saremo tutti e due gatti...

  10. #10
    Frontend samurai L'avatar di fcaldera
    Registrato dal
    Feb 2003
    Messaggi
    12,924
    ok, allora ti propongo uno script che ho abbozzato in un quarto d'ora (richiede jQuery 1.7)

    ho preparato 3 file php che ritornano un output dopo un certo tempo d'attesa

    script1.php
    codice:
    <?php sleep(4); header("Content-type: text/html"); ?>
    questo è script1
    script2.php
    codice:
    <?php sleep(2); header("Content-type: text/html"); ?>
    questo è script2
    script3.php
    codice:
    <?php sleep(6); header("Content-type: text/html"); ?>
    questo è script3
    (l'ordine di ritorno sarà script2, script1 e poi script3)
    il codice javascript che viene eseguito al domready è il seguente:

    codice:
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"> </script>
    <script>
    $(function() {
       var defer    = $.Deferred(),
           chain    = defer,
    
           input    = ["script1.php", "script2.php", "script3.php"],
           output   = [];
    
        $.map(input, function(url, i) {
                console.log("%d Ajax request: %s", i, url);
                chain = chain.pipe(function() {
                      return $.get(url).done(function(o) {
                           output[i] = o;
                      })
                });
        });
    
        chain.done(function() {  console.log(output)  });
        defer.resolve();
    });
    se conosci i deferred objects nella pratica non faccio altro che concatenare una serie di pipe() ad un master deferred ciascuna delle quali ritorna una promise (tutti i metodi relativi ad ajax ritornano sempre una promessa) e quando ciascuna promise viene risolta salvo l'output in un array ordinato

    Usa un webserver locale e attiva una console javascript per vedere l'ordine delle varie risposte e l'array ordinato di output

    come puoi notare con questo codice le chiamate ajax sono sequenziali ovvero il risultato ritorna dopo 4 + 2 + 6 = 12s

    se vuoi quella che ti posto qui sotto è la stessa versione con la notevole differenza che le chiamate ajax sono eseguite in parallelo ma mette in chain solo le singole promesse

    codice:
    $(function() {
       var defer    = $.Deferred()
           chain    = defer,
    
           input    = ["script1.php", "script2.php", "script3.php"],
           output   = [];
    
        $.map(input, function(url, i) {
                console.log("%d Ajax request: %s", i, url);
                var ajaxcall = $.get(url);
                chain = chain.pipe(function() {
                    return ajaxcall.done(function(o) {
                        output[i] = o;
                    })
                });
        });
    
        chain.done(function() {  console.log(output)  });
        defer.resolve();
    });
    questo codice stampa l'output dopo la chiamata ajax più "costosa" (ovvero dopo 6 secondi) per cui è più efficiente rispetto alla prima versione

    Nota che manca del tutto la gestione degli errori, per cui devi valutare come si deve comportare lo script nel caso in cui una o più risorse ajax non siano disponibili.
    Vuoi aiutare la riforestazione responsabile?

    Iscriviti a Ecologi e inizia a rimuovere la tua impronta ecologica (30 alberi extra usando il referral)

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.