2013-09-30 15 views
6

Piszę klienta JavaScript API przy użyciu jQuery. Moja prośba poziom top metoda wygląda następująco:Podaj domyślną metodę "fail" dla obiektu odroczonego 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(); 
}, 

Jak mogę mieć domyślny fail obsługi dla mojego wrócił odroczone? Oznacza to, że jeśli odroczony nie ma innych modułów obsługi dołączonych do jego warunku fail, wywołaj domyślną procedurę obsługi.

Chcę to zrobić, aby mieć globalną obsługę wyjątków w mojej aplikacji, z wyjątkiem części, które mają specyficzną obsługę (i zdefiniują własną obsługę fail na odroczonym).

+5

odroczone obiekty nie działają w ten sposób. Zamiast tego należy mieć globalną procedurę obsługi błędów, a następnie wyłączyć zdarzenia globalne dla tego żądania ajax. –

+0

Nie używaj tutaj interfejsu '$ .Deferred'. Po prostu wywołaj metodę 'then' (lub' pipe' w starych wersjach jQuery) na obietnicy zwróconej przez '$ .ajax()'! – Bergi

+0

Istnieje globalne zdarzenie "ajaxError" (http://api.jquery.com/ajaxError/) i można użyć ['$ .ajaxSetup'] (http://api.jquery.com/jQuery.ajaxSetup /) dla domyślnych opcji. – Bergi

Odpowiedz

3

Najczystszym sposobem na użycie jQuery ajax w interfejsie API od 2016 jest zwrócenie obietnicy. Ale nie można ustalić, czy osoba dzwoniąca załączyła procedurę obsługi błędów, czy też nie dotrzymała obietnicy.

Zasugeruję, że po prostu dodajesz nowy argument do funkcji, która mówi, że funkcja NIE stosuje domyślnej obsługi błędów, ponieważ wywołujący zajmie się obsługą błędów. A ja proponuję unikać obietnicę anty-wzorzec tylko przy użyciu istniejącego już obietnicę $.ajax() zwraca zamiast tworzenia własnych odroczony:

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; 
}; 

Następnie rozmówca właśnie decyduje, czy należy zastosować własną obsługę błędów lub nie:

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

albo można iść z non-obietnicy failHandler zwrotna, które przechodzą w domyślnym a obsługa błędów sprawdza, czy że failHandler została przyjęta czy nie. Jest to hybryda obietnic i wywołania zwrotne i nie jest coś, co normalnie wybrać architekta, ale ponieważ Twoje pytanie prosi o coś, co obiecuje nie obsługują, jest to jeden z osiągnięcia tego:

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; 
};