2012-01-12 23 views
264

Ho lavorato con jQuery e AJAX per alcune settimane e ho visto due modi diversi per "continuare" lo script una volta che la chiamata è stata effettuata: success: e .done.Gestione jQuery.ajax continue risposte: "successo:" vs ".done"?

Dalla sinossi dal jQuery documentation otteniamo:

.done(): Descrizione: Aggiungere i gestori di essere chiamato quando l'oggetto differite è stato risolto.

successo: (.ajax() opzione): una funzione da chiamare se la richiesta ha esito positivo.

Quindi, entrambi fanno qualcosa dopo che la chiamata AJAX è stata completata/risolta. Posso usare l'una o l'altra a caso? Qual è la differenza e quando uno è usato al posto dell'altro?

risposta

399

success è stato il nome tradizionale del callback di successo in jQuery, definito come un'opzione nella chiamata Ajax. Tuttavia, poiché l'implementazione di $.Deferreds e di callback più sofisticati, done è il modo migliore per implementare callback di successo, poiché può essere richiamato su qualsiasi deferred.

Ad esempio, il successo:

$.ajax({ 
    url: '/', 
    success: function(data) {} 
}); 

Per esempio, fatto:

$.ajax({url: '/'}).done(function(data) {}); 

La cosa bella di done è che il valore di ritorno di $.ajax è ora una promessa differita che può essere legato a in qualsiasi altro punto della tua applicazione. Quindi diciamo che vuoi fare questa chiamata ajax da alcuni posti diversi. Invece di passare alla funzione di successo come opzione per la funzione che effettua questa chiamata ajax, è sufficiente avere la funzione return $.ajax e associare i callback con done, fail, then o qualsiasi altra cosa. Si noti che è un callback che verrà eseguito indipendentemente dal fatto che la richiesta abbia esito positivo o negativo. done verrà attivato solo in caso di successo.

Ad esempio:

function xhr_get(url) { 

    return $.ajax({ 
    url: url, 
    type: 'get', 
    dataType: 'json', 
    beforeSend: showLoadingImgFn 
    }) 
    .always(function() { 
    // remove loading image maybe 
    }) 
    .fail(function() { 
    // handle request failures 
    }); 

} 

xhr_get('/index').done(function(data) { 
    // do stuff with index data 
}); 

xhr_get('/id').done(function(data) { 
    // do stuff with id data 
}); 

Un importante vantaggio di questo in termini di manutenibilità è che hai avvolto il meccanismo di ajax in una funzione specifica. Se decidi che la tua chiamata a $.ajax funzionerà diversamente in futuro, o se utilizzi un metodo ajax diverso o ti sposti da jQuery, devi solo modificare la definizione xhr_get (assicurandoti di restituire una promessa o almeno uno done metodo, nel caso dell'esempio sopra). Tutti gli altri riferimenti in tutta l'app possono rimanere gli stessi.

Ci sono molte cose di più (molto più fredda) si possono fare con $.Deferred, uno dei quali è quello di utilizzare pipe per innescare un guasto su un errore riportato dal server, anche quando la richiesta $.ajax si riesce.Per esempio:

function xhr_get(url) { 

    return $.ajax({ 
    url: url, 
    type: 'get', 
    dataType: 'json' 
    }) 
    .pipe(function(data) { 
    return data.responseCode != 200 ? 
     $.Deferred().reject(data) : 
     data; 
    }) 
    .fail(function(data) { 
    if (data.responseCode) 
     console.log(data.responseCode); 
    }); 
} 

xhr_get('/index').done(function(data) { 
    // will not run if json returned from ajax has responseCode other than 200 
}); 

Leggi di più riguardo $.Deferred qui: http://api.jquery.com/category/deferred-object/

NOTA: Come di jQuery 1.8, pipe è stato deprecato in favore di usare then esattamente nello stesso modo.

+2

Mi chiedo come siano definite le interazioni di 'successo:' /'.done() ', se non del tutto. Per esempio. è 'successo:' appena implementato come il primo '.done()' di questi tempi? –

+5

Vuoi dire se hai sia 'successo:' che '.done' su una chiamata ajax? Buona domanda. Dato che tutti gli altri callback sono chiamati nell'ordine in cui sono associati, la mia ipotesi è sì, "success" è appena chiamato per primo. – glortho

+1

Sì, sembra proprio il caso: http://jsfiddle.net/9L7dD/ – Adam

2

Se è necessario async: false nell'ajax, è necessario utilizzare success anziché .done. Altrimenti è meglio usare .done. Questo è da jQuery official site:

Come di jQuery 1.8, l'uso di async: false con jqXHR ($ .Deferred) è sconsigliata; si necessario utilizzare i di successo/errore/complete opzioni richiamata invece di corrispondenti metodi dell'oggetto jqXHR come jqXHR.done().

Problemi correlati