2011-01-13 20 views
10

Ho avuto problemi con la natura asincrona di Javascript/JQuery.richieste ajax multiple con jquery

Diciamo quanto segue (non viene conteggiata alcuna latenza, per non renderla così problematica);

Ho ottenuto tre pulsanti (A, B, C) su una pagina, ognuno dei pulsanti aggiunge un elemento in un carrello con una richiesta di ajax ciascuno. Se metto un ritardo intenzionale di 5 secondi nello script lato server (PHP) e spinge i bottoni con 1 secondo di distanza, voglio che il risultato sia il seguente:

Request A, 5 seconds 
Request B, 6 seconds 
Request C, 7 seconds 

Tuttavia, il risultato è come questo

Request A, 5 seconds 
Request B, 10 seconds 
Request C, 15 seconds 

Questo deve significare che le richieste sono in coda e non vengono eseguite contemporaneamente, giusto? Non è questo il contrario di ciò che è async? Ho anche provato ad aggiungere un parametro get casuale all'URL per forzare un po 'l'unicità alla richiesta, ma senza fortuna.

Ho letto un po 'su questo. Se si evita di utilizzare lo stesso "oggetto richiesta (?)", Questo problema non si verificherà. È possibile forzare questo comportamento in JQuery?

Questo è il codice che sto usando

$.ajax(
{ 
    url : strAjaxUrl + '?random=' + Math.floor(Math.random()*9999999999), 
    data : 'ajax=add-to-cart&product=' + product, 
    type : 'GET', 
    success : function(responseData) 
    { 
    // update ui 
    }, 
    error : function(responseData) 
    { 
    // show error 
    } 
}); 

Ho anche provato sia GET e POST, nessuna differenza.

Desidero che le richieste vengano inviate correttamente quando si fa clic sul pulsante, non quando la richiesta precedente è finita. Voglio che le richieste vengano eseguite contemporaneamente, non in una coda.

+1

Puoi pubblicare qui il tuo codice javascript. Di default '$ .ajax' è asincrono –

+0

@Emil, rimuovi Math.Random ecc. E semplicemente usa' cache: false' – Anders

+0

Ho pensato che jquery usi una nuova connessione asincrona per ogni chiamata. –

risposta

8

Ok, ecco quello che proverei, penso che sia necessario un modo migliore per registrare l'ora. Non sono sicuro di cosa stai facendo ora per testare i tempi ma qui è un buon modo.

Ottieni Firebug per Firefox se non lo hai già fatto.

Apri Firebug e vai alla scheda di rete. Assicurati di abilitarlo.

Mentre si fa clic su ciascun pulsante, è necessario visualizzare ogni richiesta in arrivo. Se si fa clic su ciascun pulsante, non si vede la successiva richiesta che inizia fino a quando la richiesta precedente non è terminata, quindi mi viene indicato che c'è qualcosa di sbagliato in javascript. Tuttavia, suppongo che l'inizio di ogni barra sia di 1 secondo di distanza. Fai questo e facci sapere cosa vedi.

Modifica

Credo di avere trovato voi problema. Sto indovinando che stai usando la funzione sleep in php. La funzione sleep è attiva per la sessione corrente. Se apri 3 schede e inserisci l'URL ajax, noterai lo stesso comportamento. 5, 10, quindi 15 secondi per ogni tab per finire. Ho provato su google e ho trovato gli stessi risultati con altre persone. Questo è probabilmente perché PHP non è realmente multithread. Suggerisco di utilizzare un framework diverso.

+0

Io uso Firebug per registrare i tempi. Pensavo fosse ovvio, non un noob a questo scopo .. – Emil

+0

Puoi mostrare uno screenshot della scheda di rete per favore. –

+0

http://data.fuskbugg.se/dipdip/_net.png – Emil

0

Da quello che ho capito Le chiamate ajax parallele possono essere eseguite solo se non si è in un ambito diverso di js. Sembra che essere nello stesso stesso ambito js ti faccia usare lo stesso 'oggetto richiesta' in modo serializzato.

Quindi possiamo trovare su Stack overflow due eccellenti risposte su questo alla pagina collegata, vedere la seconda risposta con un oggetto parallelo stack di query, questa è la cosa che ti serve, aggiungi le tue richieste su questo stack parallelo e saranno davvero essere licenziato in parallelo (Stack overflow è il miglior sito nel web :-)). Parallel asynchronous Ajax requests using jQuery

+0

Lo farò, dai un'occhiata, grazie! – Emil

+0

Il codice mostrato nell'altro thread è il codice per un ciclo e chiamate ajax nel ciclo, giusto?Voglio effettuare una chiamata ajax su ogni evento che verrà eseguito "l'uno accanto all'altro" senza scontrarsi – Emil

+0

la prima risposta è con un ciclo, il secondo esempio fornisce un oggetto che gestisce la coda di query, nel tuo caso l'utilizzo di questo oggetto dovrebbe adattarsi al tuo è necessario, sarà probabilmente necessario utilizzare jQuery.data per archiviare la coda di query in modo indipendente dall'ambito js. – regilero

0

non si può fare simultaneamente, causare JS hanno finte operazioni asincrone a causa di un unico browser thread dell'interfaccia utente. Ma puoi provare Web Workers, il modo di eseguire il outsude del codice del thread dell'interfaccia utente del browser. Hanno già supportato Firefox 3.5, Chrome 3 e Safari 4. Forse migliorerà l'usabilità dell'applicazione

3

Apparentemente questo comportamento è facilmente passabile utilizzando session_write_close(); in PHP. Tuttavia, questo si apre facilmente agli attacchi DDos. Ho aggiornato una pagina tenendo premuto F5 in 10 secondi e ucciso il mio computer di sviluppo in nessun tempo.

Caso chiuso.

+0

Emil Ho trascorso molto tempo e ti ho trovato una soluzione. Ma hai scritto la stessa risposta e l'hai accettata come corretta. Potresti aver dato credito ad alcuni membri della comunità invece di te stesso. –

+0

Fatto, spiacente amico. E grazie Amir per l'aiuto! Lo apprezzo molto! :) – Emil