2013-09-30 12 views
6

Sto scrivendo un client API Javascript utilizzando jQuery. Il mio metodo di richiesta di alto livello simile a questo:Fornire un metodo "fail" predefinito per un oggetto differito jQuery

function request(method, uri, params, proxies) { 
    var deferred = $.Deferred(); 
    $.ajax({ 
    data: method == 'GET' ? params : JSON.stringify(params), 
    contentType: 'application/json', 
    dataType: 'json', 
    url: api.root + uri, 
    type: method, 
    xhrFields: { 
     withCredentials: true 
    } 
    }).done(function(body) { 
    deferred.resolveWith(this, [body.data]); 
    }).fail(function(xhr) { 
    deferred.rejectWith(this, [xhr]); 
    }); 

    return deferred.promise(); 
}, 

Come posso avere un gestore predefinito per il mio fail restituito differita? Cioè, se il rinviato non ha altri gestori collegati alla sua condizione fail, chiama un gestore predefinito.

Voglio farlo per avere una gestione globale delle eccezioni nella mia applicazione, ad eccezione delle parti che hanno una gestione specifica (e definiremo il proprio gestore fail in differita).

+5

oggetti differite non funzionano quel modo. Invece, avere un gestore di errori globale e quindi disabilitare gli eventi globali per quella richiesta Ajax. –

+0

Non utilizzare l'interfaccia '$ .Deferred' qui. Basta chiamare il metodo 'then' (o' pipe' nelle vecchie versioni di jQuery) sulla promessa restituita da '$ .ajax()'! – Bergi

+0

C'è un evento globale ['ajaxError'] (http://api.jquery.com/ajaxError/), e puoi usare [' $ .ajaxSetup'] (http://api.jquery.com/jQuery.ajaxSetup /) per le opzioni predefinite. – Bergi

risposta

3

Quindi, il modo più semplice per utilizzare jQuery ajax in un'API a partire dal 2016 è di restituire una promessa. Tuttavia, non è possibile determinare se un chiamante ha collegato un gestore errori o meno alla promessa.

Quindi, quello che suggerirei è che basta aggiungere un nuovo argomento alla propria funzione che indica alla funzione di NON applicare la gestione degli errori predefinita perché il chiamante si occuperà della gestione degli errori. E, io suggerirei di evitare la promessa anti-modello da solo utilizzando la promessa esistente $.ajax() restituisce già piuttosto che creare il proprio anticipate:

function request(method, uri, params, proxies, skipDefaultErrorHandling){ 
    // default error handling will be used if nothing is passed 
    // for skipDefaultErrorHandling 
    var p = $.ajax({ 
     data: method=='GET'?params:JSON.stringify(params), 
     contentType: 'application/json', 
     dataType: 'json', 
     url: api.root + uri, 
     type: method, 
     xhrFields: { 
      withCredentials: true 
     } 
    }); 
    if (!skipDefaultErrorHandling) { 
     // apply default error handling 
     p = p.then(null, function(jqXHR, textStatus, errorThrown) { 
      // put here whatever you want the default error handling to be 
      // then return the rejection with the various error parameters available 
      return $.Deferred().reject([jqXHR, textStatus, errorThrown]); 
     }); 
    } 

    return p; 
}; 

Poi, il chiamante decide solo se applicare la propria gestione degli errori o non:

request(...).then(function(data) { 
    // success code here 
}); 

in alternativa, si può andare con un non-promessa failHandler callback che si passa e la vostra gestione degli errori di default sembra di vedere se questo failHandler è stata approvata o meno. Questo è ibrido di promesse e di callback e non è qualcosa che normalmente scegliere di architetto, ma dal momento che la tua domanda chiede qualcosa che promette non supportano, questo è uno dei raggiungimento di tale:

function request(method, uri, params, proxies, failHandler){ 
    // default error handling will be used if nothing is passed 
    // for skipDefaultErrorHandling 
    var p = $.ajax({ 
     data: method=='GET'?params:JSON.stringify(params), 
     contentType: 'application/json', 
     dataType: 'json', 
     url: api.root + uri, 
     type: method, 
     xhrFields: { 
      withCredentials: true 
     } 
    }); 
    // apply default error handling 
    p = p.then(null, function(jqXHR, textStatus, errorThrown) { 
     if (failHandler) { 
      // call passed in error handling 
      failHandler.apply(this, arguments); 
     } else { 
      // do your default error handling here 
     } 
     // then keep the promise rejected so the caller doesn't think it 
     // succeeded when it actually failed 
     return $.Deferred().reject([jqXHR, textStatus, errorThrown]); 
    }); 

    return p; 
}; 
Problemi correlati