jQuery.ajax gestendo le risposte continue: "successo:" vs ".done"?


309

Lavoro con jQuery e AJAX da alcune settimane e ho visto due modi diversi di "continuare" lo script una volta effettuata la chiamata: success:e .done.

Dalla sinossi della documentazione di jQuery otteniamo:

.done (): Descrizione: Aggiungi gestori da chiamare quando l'oggetto Deferred viene risolto.

successo: (opzione .ajax ()): 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'uno o l'altro a caso? Qual è la differenza e quando viene utilizzato uno anziché l'altro?

Risposte:


469

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

Ad esempio, successo:

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

Ad esempio, fatto:

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

La cosa bella doneè che il valore di ritorno di $.ajaxè ora una promessa differita che può essere legata a qualsiasi altra parte dell'applicazione. Quindi supponiamo che tu voglia effettuare questa chiamata Ajax da diversi posti. Invece di passare nella funzione di successo come opzione per la funzione che rende questa chiamata ajax, si può solo avere la funzione di ritorno $.ajaxin sé e si legano i tuoi callback con done, fail, then, o qualsiasi altra cosa. Si noti che alwaysè un callback che verrà eseguito se la richiesta ha esito positivo o negativo. doneverrà attivato solo in caso di successo.

Per 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 vantaggio importante di ciò in termini di manutenibilità è che hai avvolto il tuo meccanismo Ajax in una funzione specifica dell'applicazione. Se decidi di avere bisogno che la tua $.ajaxchiamata funzioni in modo diverso in futuro, o usi un metodo ajax diverso o ti allontani da jQuery, devi solo cambiare la xhr_getdefinizione (assicurandoti di restituire una promessa o almeno un donemetodo, in il caso dell'esempio sopra). Tutti gli altri riferimenti in tutta l'app possono rimanere gli stessi.

Ci sono molte altre cose (molto più interessanti) che puoi fare $.Deferred, una delle quali è quella pipedi innescare un errore su un errore segnalato dal server, anche quando la $.ajaxrichiesta stessa ha esito positivo. 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
});

Maggiori informazioni $.Deferredqui: http://api.jquery.com/category/deferred-object/

NOTA : A partire da jQuery 1.8, pipeè stato deprecato a favore dell'uso thenesattamente allo stesso modo.


2
Mi chiedo come siano definite le interazioni di success:/ .done(). Ad esempio è success:appena implementato come il primo in .done()questi giorni?

6
Vuoi dire se hai entrambi success:e .donesu una chiamata Ajax? Buona domanda. Dal momento che tutti gli altri callback vengono chiamati nell'ordine in cui sono associati, la mia ipotesi è sì, successviene chiamato per primo.
glortho,

1
Post molto bello! A proposito, nel callback di pipe, non dovresti chiamare la funzione pipe con il parametro jqXHR per verificare la risposta dello stato? Esempio: .pipe (funzione (data, textStatus, jqXHR) {if (jqXHR.status == 200) {...
Eder

@Eder Lo scenario che sto affrontando con questo uso pipeè quello in cui la richiesta stessa ha esito positivo ma lo script sul server non ha restituito quello che stavi cercando. Potresti non voler lanciare un 404 o 500 effettivo o qualsiasi altra cosa sul lato server perché vuoi distinguere significativamente tra le risposte http e le risposte dell'applicazione. L'impostazione di un codice di risposta in JSON e l'utilizzo in pipequesto modo consente di gestire diversi tipi di errori con più sfumature.
glortho,

Un altro importante vantaggio dell'utilizzo delle promesse è che il codice diventa molto più leggibile ed evita l'inferno di richiamata. Ciò è particolarmente vero quando si hanno più callback che si desidera eseguire ciascuno dopo il precedente. Con le promesse sembrerebbe myPromiseCall.then (..). Then (..) invece della struttura complicata nidificata di callback utilizzata con l'opzione success.
BornToCode

5

Se hai bisogno async: falsenel tuo Ajax, dovresti usare successinvece di .done. Altrimenti è meglio usarlo .done. Questo è dal sito ufficiale di jQuery :

A partire da jQuery 1.8, l'uso di async: false con jqXHR ($ .Deferred) è obsoleto; è necessario utilizzare le opzioni esito positivo / errore / callback completo anziché i metodi corrispondenti dell'oggetto jqXHR come jqXHR.done () .


Di chi parla async:false?
Liam,

$.ajax({ url: req_url, ..., async: false, success: function (result, status, req) { }, error: function (jqXHR, status) { } });
AmirHossein Manian,

0

Dalla documentazione di JQuery

Gli oggetti jqXHR restituiti da $.ajax()jQuery 1.5 implementano l'interfaccia Promise, fornendo loro tutte le proprietà, i metodi e il comportamento di una Promessa (vedi Oggetto differito per ulteriori informazioni). Questi metodi accettano uno o più argomenti di funzione che vengono chiamati al termine della $.ajax()richiesta. Ciò consente di assegnare più callback su una singola richiesta e persino di assegnare callback dopo il completamento della richiesta. (Se la richiesta è già completa, il callback viene attivato immediatamente.) I metodi Promise disponibili dell'oggetto jqXHR includono:

jqXHR.done(function( data, textStatus, jqXHR ) {});

Un costrutto alternativo all'opzione callback riuscita, fare riferimento deferred.done()per i dettagli di implementazione.

jqXHR.fail(function( jqXHR, textStatus, errorThrown ) {});

Un costrutto alternativo all'opzione di callback dell'errore, il .fail()metodo sostituisce il metodo obsoleto .error (). Fare riferimento a deferred.fail () per i dettagli sull'implementazione.

jqXHR.always(function( data|jqXHR, textStatus, jqXHR|errorThrown ) { }); 

(aggiunto in jQuery 1.6) Un costrutto alternativo all'opzione di callback completa, il .always()metodo sostituisce il .complete()metodo deprecato .

In risposta a una richiesta corretta, gli argomenti della funzione sono gli stessi di .done(): data, textStatus e l'oggetto jqXHR. Per richieste non riuscite, gli argomenti sono gli stessi di .fail(): l'oggetto jqXHR, textStatus ed errorThrown. Fare riferimento a deferred.always()per i dettagli di implementazione.

jqXHR.then(function( data, textStatus, jqXHR ) {}, function( jqXHR, textStatus, errorThrown ) {});

Incorpora la funzionalità dei metodi .done()e .fail(), consentendo (a partire da jQuery 1.8) di manipolare la Promessa sottostante. Fare riferimento a differito .then()per i dettagli di implementazione.

Deprecazione Avviso: Il jqXHR.success(), jqXHR.error()e jqXHR.complete()callback vengono rimossi come di jQuery 3.0. È possibile utilizzare jqXHR.done(), jqXHR.fail()e jqXHR.always()invece.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.