2013-01-18 11 views
17

ho trovato questo frammento di codice che fa quello che voglio che:Promesse jQuery e Backbone

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

Voglio tornare il responseText dalla mia chiamata spina dorsale per this.model.save(). Questo codice è stato documentato here. Ma non sta registrando nulla, anche se estraggo una stringa di testo non elaborata nella chiamata console.log().

Qualcuno potrebbe spiegare in parole povere cosa è una promessa di jQuery? Ho letto di loro, ma non credo di aver capito cosa fossero. Questo potrebbe aiutarmi a capire perché questo codice non funziona per me. Se I console.log(promise) tra la prima e la seconda riga di codice, ottengo il responseText. Quindi qualcosa sta succedendo nel $.when o nello then che sta causando un errore.

EDIT:

Dopo aver letto l'articolo, ho scoperto che potevo fare questo:

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

Ma io non capisco cosa il null rappresenta. then sembra prendere due parametri, una funzione di successo e una funzione di errore. Ma la funzione di successo non sarebbe la prima? Ottengo una risposta 200 dal server.

+0

leggere questo http://css.dzone.com/articles/exploring-deferred-and-promise –

+0

Sembra un buon articolo. Grazie. – sehummel

+0

non è eccessiva :) lettura felice .. –

risposta

26

Quindi, per prima cosa, sono abbastanza sicuro che non è necessario la parte when; Dalla documentazione jQuery:

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).

Dal Promessa ha già il metodo then, basta che si può fare:

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

(Il fatto che il codice di cui sopra quasi si legge come una frase in inglese è uno dei principali vantaggi di usando Deferreds, almeno per me.)

Per quanto riguarda l'argomento null, i documenti sono di nuovo abbastanza chiari. Ci sono tre firme per then (e questo è solo per coprire le diverse versioni di jQuery; qualsiasi versione conta meno):

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

deferred.then(doneCallbacks, failCallbacks)

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

Come potete vedere, tutti e tre prendono la funzione di "fatto" prima, e la funzione di fallimento secondo. Ciò sembra implicare che stai ottenendo un fallimento, che è fonte di confusione. Un modo per evitare il problema è non usare affatto then. Invece, prova quanto segue:

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

Ciò renderà la funzione richiamata indipendentemente da ciò che accade.Tuttavia, probabilmente dovrebbe capire cosa sta succedendo, così si potrebbe desiderare di aggiungere invece un successo e il fallimento di callback per fare un po 'di debug:

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

Quali sono i vantaggi di utilizzare jQuery di differita al posto dei callback backbone di pianura, come questi? 'this.model.save ({successo: function() {} , errore: function() {}} );' – Ingro

+2

E 'solo stile davvero. Se stai facendo cose complesse (come dire due chiamate AJAX, dove il secondo ha bisogno di dati che tornano dal primo), lo stile Deferred ti consente di farlo in modo molto elegante. Altrimenti, però, è solo questione di come si vuole modellare il codice. E in realtà questo non è nemmeno un problema specifico di Backbone; nel semplicemente vecchio jQuery si hanno anche '$ .ajax ({successo: handler});' vs, '$ .ajax ({}) Done (handler)' tra cui scegliere.. – machineghost

+0

@machineghost. Grazie per la tua risposta molto approfondita. Questo spiega molto. – sehummel

7

Perché this.model.save restituisce una promessa, è possibile effettuare le seguenti operazioni, invece:

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

(. Questo è più facile che l'intero $.when bit)

La mia ipotesi è che anche se la vostra risposta restituisce un codice 200 , è ancora "in errore" perché il tipo di dati di risposta non corrisponde a ciò che si aspetta (cosa è impostato nell'attributo dataType nella chiamata $.ajax).

0

Io sono un grande fan di utilizzare promessa, e penso che i mezzi promessa cose molto simili in diversi pacchetti.

Per rispondere alla tua domanda, che le risposte precedenti non ha fatto, il "poi" la funzione è una funzione di una promessa, il "quando" la funzione è un fail-Save, in caso l'oggetto non è una promessa, un "quando (obj) "farà in modo che sia una promessa, in modo che tu possa usare l'elegante xxx.then (success() {}, error() {}).

btw, il "rinviato" che machineghost ha detto è il pacchetto che consente di utilizzare la promessa. Per iniziare a conoscere la promessa e come usarla. dai un'occhiata a questo tutorial. Spiega ogni cosa molto chiaramente, è l'articolo che mi ha fatto promettere. http://strongloop.com/strongblog/promises-in-node-js-with-q-an-alternative-to-callbacks/

Ora, come ha detto machineghost, sembra la chiamata di sincronizzazione è sempre un errore, in base a una documentazione API REST, https://parse.com/docs/rest# (non so se è la stessa di spina dorsale), il server sarà la risposta di un JSON oggetto di una richiesta di "creare" in questo formato:

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

la mia ipotesi è, forse il vostro server non ha risposto alla richiesta con il JSON corretta, in modo che il save() pensare l'operazione non è riuscita perché non c'era "createAt "campo, evento pensato che il tuo server ha creato l'oggetto.

Problemi correlati