web-dev-qa-db-fra.com

jQuery Promises et Backbone

J'ai trouvé cet extrait de code qui fait ce que je veux:

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

Je souhaite récupérer la responseText de mon appel au backbone à this.model.save(). Ce code a été documenté ici . Mais il n'enregistre rien, même si je tire une chaîne de texte brut dans l'appel console.log().

Quelqu'un pourrait-il expliquer en termes simples la promesse de jQuery? J'ai lu sur eux, mais je ne pense pas avoir tout à fait ce qu'ils étaient. Cela pourrait m'aider à comprendre pourquoi ce code ne fonctionne pas pour moi. Si je console.log(promise) entre les première et deuxième lignes de code, alors je reçois la responseText. Il se passe donc quelque chose dans le $.when ou le then qui cause le problème.

MODIFIER: 

Après avoir lu l'article, j'ai découvert que je pouvais le faire:

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

Mais je ne comprends pas ce que représente la null. then semble prendre deux paramètres, une fonction de succès et une fonction d'échec. Mais la fonction de réussite ne serait-elle pas la première? Je reçois une réponse 200 du serveur.

18
sehummel

Alors d’abord, je suis presque sûr que vous n’avez pas besoin de la partie when; à partir de la documentation jQuery:

Les objets jqXHR renvoyés par $ .ajax () à partir de jQuery 1.5 implémentent l'interface Promise, en leur donnant toutes les propriétés, méthodes et le comportement D'une promesse (voir Objet différé pour plus d'informations). .

Puisque Promise a déjà une méthode then, vous pouvez simplement faire:

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

(Le fait que le code ci-dessus se lit presque comme une phrase en anglais constitue un avantage majeur de l'utilisation de l'option Différé, du moins pour moi.)

En ce qui concerne votre argument null, la documentation est à nouveau assez claire. Il y a trois signatures pour then (et cela ne concerne que les différentes versions de jQuery; toute version en contient moins):

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

deferred.then (doneCallbacks, failCallbacks)

deferred.then (doneCallbacks, failCallbacks [ progressCallbacks])

Comme vous pouvez le constater, tous les trois prennent la fonction "terminé" en premier et la fonction échec en second. Cela semble impliquer que vous obtenez un échec, ce qui est déroutant. Une façon d'éviter le problème est de ne pas utiliser then du tout. Au lieu de cela, essayez ce qui suit:

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

Cela fera que votre fonction sera appelée peu importe ce qui se passera. Cependant, vous devriez probablement savoir ce qui se passe, alors vous voudrez peut-être ajouter un rappel de succès et d'échec pour effectuer le débogage:

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

Étant donné que this.model.save renvoie une promesse, vous pouvez effectuer les opérations suivantes:

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

(C'est plus facile que le $.when entier.)

Je suppose que bien que votre réponse renvoie un code 200, elle échoue toujours car le type de données de la réponse ne correspond pas à ce que vous attendez (définition de l'attribut dataType dans l'appel $.ajax).

7
Lukas

Je suis un grand fan de l'utilisation de la promesse, et je pense que la promesse signifie des choses très similaires dans différents forfaits. 

Pour répondre à votre question, ce que les réponses précédentes ne faisaient pas, la fonction "then" est une fonction d'une promesse, la fonction "when" est une sauvegarde automatique, dans le cas où l'objet n'est pas une promesse, un "when (obj)" s'assurera que c'est une promesse, afin que vous puissiez utiliser l'élégant xxx.then (success () {}, error () {}). 

en fait, le "différé" que machineghost a dit est le paquet qui vous permet d'utiliser promesse. Pour avoir commencé à connaître la promesse et à l’utiliser. consultez ce tutoriel. Cela explique tout très clairement, c’est l’article qui m’a fait faire de telles promesses. http://strongloop.com/strongblog/promises-in-n-node-js-with-q-an-alternative-to-callbacks/

Maintenant, comme le dit machineghost, il semble que votre appel de synchronisation reçoive une erreur, selon une REST API documentation, https://parse.com/docs/rest# (ne sait pas s'il s'agit du même réseau que le backbone), le serveur répondra à un objet JSON pour une requête "create" au format suivant:

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

J'imagine que votre serveur n'a peut-être pas répondu à la requête avec le bon JSON. Par conséquent, save () pense que l'opération a échoué car il n'y avait pas de champ "createAt", l'événement pensait que votre serveur avait créé l'élément. 

0
Evilsanta