2013-01-18 11 views
17

finde ich diesen Code-Snippet, das tun, was ich will, es zu:jQuery Versprechen und Backbone

var promise = this.model.save(); 
$.when(promise).then(function() { 
    console.log(promise.responseText); 
}); 

Ich mag this.model.save() die responseText von meinem Backbone Anruf zurück zu bekommen. Dieser Code wurde dokumentiert here. Aber es protokolliert nichts, selbst wenn ich eine unverarbeitete Zeichenkette im console.log()-Aufruf abrufe.

Könnte jemand bitte erklären, was ein jQuery Versprechen ist? Ich habe über sie gelesen, aber ich glaube nicht, dass ich wirklich verstanden habe, was sie sind. Das könnte mir helfen zu verstehen, warum dieser Code nicht für mich funktioniert. Wenn ich console.log(promise) zwischen der ersten und der zweiten Zeile Code, dann bekomme ich die responseText. So etwas passiert entweder in der $.when oder der then, die dies verursacht schief gehen.

EDIT:

Nach dem Lesen des Artikels, ich entdeckte ich dies tun könnte:

var promise = this.model.save(); 
$.when(promise).then(null, function(obj) { 
    console.log(obj.responseText); 
}); 

Aber ich verstehe nicht, was die null darstellt. then scheint zwei Parameter zu nehmen, eine Erfolgsfunktion und eine Fehlerfunktion. Aber wäre die Erfolgsfunktion nicht zuerst? Ich bekomme eine 200 Antwort vom Server.

+0

lesen Sie http://css.dzone.com/articles/exploring-deferred-and-promise –

+0

Es ist wie ein guter Artikel aussieht. Vielen Dank. – sehummel

+0

keine probs :) Viel Spaß beim Lesen .. –

Antwort

26

Also erstmal, ich bin mir ziemlich sicher, dass Sie den when Teil nicht brauchen; von den jQuery docs:

The jqXHR objects returned by $.ajax() as of jQuery 1.5 implement the Promise interface, giving them all the properties, methods, and behavior of a Promise (see Deferred object for more information).

Da Versprechen bereits eine then Methode hat, können Sie einfach tun:

this.model.save().then(null, function(obj) { 
    console.log(obj.responseText); 
}); 

(Die Tatsache, dass der obige Code liest sich fast wie ein englischer Satz ist ein großer Vorteil Verwenden von Deferreds, für mich mindestens.)

Wie für Ihre null Argument sind die Dokumente wieder ziemlich klar. Es gibt drei Unterschriften für then (und das ist nur die verschiedenen jQuery Versionen abzudecken; jede gegebene Version weniger hat):

deferred.then(doneFilter [, failFilter ] [, progressFilter ])

deferred.then(doneCallbacks, failCallbacks)

deferred.then(doneCallbacks, failCallbacks [, progressCallbacks ])

Wie Sie sehen können, die alle drei die „done“ Funktion übernehmen ersten und der Funktionsausfall zweite. Dies scheint zu implizieren, dass Sie einen Fehler bekommen, der verwirrend ist. Eine Möglichkeit, das Problem zu vermeiden, besteht darin, then überhaupt nicht zu verwenden. Versuchen Sie stattdessen Folgendes:

this.model.save().always(function(obj) { 
    console.log(obj.responseText); 
}); 

Dadurch wird Ihre Funktion aufgerufen, egal was passiert.Allerdings sollten Sie wahrscheinlich herausfinden, was los ist, so dass Sie vielleicht ein Erfolg und Misserfolg Rückruf zu tun einige Debuggen stattdessen hinzufügen möchten:

this.model.save().done(function() { 
    // Success case 
}).fail(function() { 
    // Failure case 
}); 
+0

Was sind die Vorteile der Verwendung von jQuery sind anstelle der einfachen Rückgrat Rückrufe verschoben, wie diese? 'this.model.save ({Erfolg: function() { }, Fehler: function() { }});' – Ingro

+2

Es ist wirklich einfach Stil. Wenn Sie komplexe Dinge tun (wie sagen zwei AJAX Anrufe machen, wo die zweite braucht man Daten, die von der ersten kommt zurück), dann die latenten Stil lässt tun Sie, dass es sehr elegant. Ansonsten ist es nur eine Frage, wie Sie Ihren Code stylen möchten. Und das ist wirklich nicht einmal ein Backbone-spezifisches Problem; in einfach nur alte jQuery haben Sie auch '$ Schnipsel ({Erfolg: Handler});' vs, '$ Schnipsel ({}) done (Handler)' zur Auswahl.. – machineghost

+0

@ maschineghost. Vielen Dank für Ihre sehr ausführliche Antwort. Das erklärt viel. – sehummel

7

Weil this.model.save ein Versprechen gibt, können Sie die stattdessen folgendes tun:

this.model.save() 
    .done(function(response) { 
     console.log("Success!"); 
    }) 
    .fail(function(response) { 
     console.log("Error!"); 
    }); 

(. Das ist einfacher, als die ganze $.when Bit)

Meine Vermutung ist, dass, obwohl Ihre Antwort zurückgibt einen 200-Code Es ist immer noch "fehlgeschlagen", da der Antwortdatentyp nicht mit dem übereinstimmt, was Sie erwarten (was im dataType-Attribut im $.ajax-Aufruf festgelegt ist).

0

Ich bin ein großer Fan von mit Versprechen, und ich denke, die Versprechen Mittel sehr ähnliche Dinge in verschiedenen Paketen.

Um Ihre Frage zu beantworten, welche vorherigen Antworten nicht, ist die "then" -Funktion eine Funktion eines Versprechens, die "when" -Funktion ist ein Fail-save, wenn das Objekt kein Versprechen ist, ein "wenn (obj)“wird sicherstellen, dass es ist ein Versprechen, so dass Sie das elegante xxx.then verwenden (Erfolg() {}, Fehler() {}).

btw, sagte der „latenten“ dass machineghost das Paket, das Sie versprechen verwenden lassen. Für das Beginnen, Versprechen zu kennen und wie man es benutzt. Schau dir dieses Tutorial an. Es erklärt alles sehr klar, es ist der Artikel, der mich zu Versprechen gemacht hat. http://strongloop.com/strongblog/promises-in-node-js-with-q-an-alternative-to-callbacks/

Jetzt, da machineghost sagte, es scheint Synchronisierungs Anruf erhalten eine Fehlermeldung, nach einer REST-API-Dokumentation, https://parse.com/docs/rest# (weiß nicht, ob es die gleiche wie Rückgrat ist), wird die Server-Antwort ein JSON Objekt für eine Anforderung in diesem Format „create“:

{"createdAt": "2011-08-20T02:06:57.931Z","objectId": "Ed1nuqPvcm"} 

Meine Vermutung ist, vielleicht der Server die Anfrage mit der richtigen JSON nicht reagiert haben, so dass die save() denken, der Vorgang fehlgeschlagen ist, weil es keine „war createAt "Feld, Ereignis dachte, dass dein Server den Gegenstand erstellt hat.