2013-07-23 7 views
22

Fyi, ich fange gerade an, jQuery Versprechungen zu erlernen, also kann ich hier ein wenig verwirrt sein.jQuery Deferred: Eine Versprechung innerhalb eines Fertigfilters zurückweisen

Wie dem auch sei, ich habe eine AJAX-Anforderung, die ich innerhalb eines getan Filter ablehnen möchten basierend auf dem Inhalt der Antwort:

return doAJAXRequest().then(function (data) { 
    if (data.responseText == "YES") { 
     return doOtherAJAXRequest(); 
    } else { 
     this.reject(data); 
    } 
}); 

, die nicht funktioniert, wie ich erwartet hatte:

Uncaught TypeError: Object #<Object> has no method 'reject' 

Wie kann ich dieses Versprechen basierend auf seiner Antwort fehlschlagen lassen? Ist das möglich? Oder bin ich nur verwirrt darüber, was hier zu tun ist?

+0

Versuchen Sie, this.reject auf $ (this) .reject zu ändern. – rtimoshenko

+0

@rtimoshenko Sind Sie sicher, dass das richtig ist? – alex

+0

@rtimoshenko Das scheint nicht zu funktionieren, ich bekomme immer noch den gleichen Fehler. Edit: Eigentlich ist es nicht genau das gleiche, aber immer noch sehr ähnlich. ('Uncaught TypeError: Objekt [Objekt Objekt] hat keine Methode 'ablehnen') – Ajedi32

Antwort

31

In jQuery (im Gegensatz zu einigen anderen Bibliotheken) ist die Umwandlung eines Versprechens von einem "aufgelösten" Zustand in einen "abgelehnten" Zustand ein wenig wortreich und erfordert die explizite Erstellung und Zurückweisung eines neuen Deferred.

function foo() { 
    return doAJAXRequest().then(function (data, textStatus, jqXHR) { 
     if (data.responseText == "YES") { 
      return doOtherAJAXRequest(data); 
     } else { 
      return $.Deferred().reject(jqXHR, data, 'Not YES').promise(); 
     } 
    }); 
) 

Hier kehrte das Versprechen, wenn data.responseText !== "YES" nachahmt (teilweise) eine Ajax-Anforderung ist fehlgeschlagen, während noch data erlaubt weitergegeben werden. Dies ist (wahrscheinlich) wichtig für den nachgelagerten .fail() -Handler, der sowohl echte Ajax-Fehler als auch transmogrifizierte Erfolgsbedingungen behandeln muss, ohne zu wissen, welcher aufgetreten ist, bis er errorThrown liest.

foo().fail(function(jqXHR, textStatus, errorThrown) { 
    if(errorThrown == 'Not YES') { 
     //transmogrified success 
     var data = textStatus; 
     ... 
    } 
    else { 
     //genuine ajax failure 
     ... 
    } 
}); 

Im Allgemeinen ist es einfacher data auf diese Weise passieren, anstatt es von dem Objekt jqXHR wieder zu erhalten. Dies gilt insbesondere für JSON-codierte Daten, die andernfalls im Fail-Handler ein zweites Mal dekodiert werden müssten.

+2

Ich glaube nicht, dass der promise() Teil benötigt wird (oder nicht mehr), was den Aufruf zu einem macht etwas weniger hässlich/länglich. – mikus

Verwandte Themen