web-dev-qa-db-fra.com

jquery quand / alors (aussi quand / fait) n'attend pas

J'ai regardé de nombreux exemples qui utilisent cette syntaxe, mais je ne vois pas ce que je fais mal. La fonction "then" est en cours d'exécution avant le retour de l'appel ajax.

J'ai également essayé d'utiliser $ .deferred et quelques autres modèles en vain.

Quelqu'un peut-il voir ce qui me manque?

J'ai débogué et je peux voir les appels effectués depuis l'intérieur du done/puis avant que l'appel ajax ne renvoie ses données de réussite (ou d'erreur).

Merci pour toute aide.

Appel principal:

this.addFirstTask = function(task) {
    var totalHours = GetHours();
    $.when(totalHours).done(function (data) {
        task.TaskHours(data);
        self.add(task);
    });
};

Il appelle la fonction ajax suivante:

function GetHours() {
    $.ajax({
        url: "/api/tst/GetMyData",
        type: 'GET',
        dataType: 'json',

        success: function(data) {
           return data;
        },

        error: function(data) {
            return 0;
        }
    });
};

Merci!

post mortem:

en plus d'ajouter le retour à l'appel ajax, selon des conseils supplémentaires, j'ai supprimé le succès et l'erreur de l'appel ajax et changé addFirstTask en:

this.addFirstTask = function(task) {
    var totalHours = GetHours();
    $.when(totalHours)
     .then(function (data) {task.TaskHours(data);})
     .done(function () { self.add(task); });
};

Si GetHours réussit, je mets à jour la valeur TaskHours. S'il échoue, je le saute juste. J'ai réalisé que DONE est comme un "ENFIN" dans le try/catch de .NET. Donc, plutôt que d'ajouter la tâche immédiatement, puis de laisser ma liaison observable la mettre à jour lorsque la valeur revient, même self.add fait partie de l'appel asynchrone.

16
Julie Lerman
function GetHours() {
    return $.ajax({
        ...
    });
};

$ .ajax () renvoie une promesse. $ .when () prend une collection de promesses, et retourne une promesse qui se termine lorsque toutes les promesses d'entrée sont terminées. fonction arg lorsque la promesse se résout avec succès.

ainsi, votre GetHours doit renvoyer une promesse que when () peut boucler, et vous appelez then () on. vous pouvez en fait ignorer la partie quand () et simplement appeler .then au retour de GetHours.

vous n'obtenez pas d'erreur parce que .when () prend également n'importe quel ancien objet, et s'il n'implémente pas l'interface Promise, il le traite simplement comme une promesse déjà terminée.

28
Andy Smith

Ce n'est pas le problème des PO, mais j'ai eu quelque chose de similaire et c'est parce que j'appelais $ .when (...) de manière incorrecte en passant un tableau de promesses.

Selon la documentation de jQuery.when si vous voulez attendre plusieurs objets différés, vous devez effectuer l'appel en tant que tel:

$.when( d1, d2 ).then(....);

Cela signifie que si vous avez plusieurs objets différés dans un tableau, vous devez utiliser appliquer (...) , sinon $ .when ne fonctionnera pas correctement. Ainsi, votre appel à un tableau d'objets différés ressemblerait à ceci:

$.when.apply(this, arrayOfDeferred).then(....);

Voici un JS Fiddle démontrant cela:

https://jsfiddle.net/Lvo4hrez/11/

8
kroolk

Vous devez renvoyer le résultat de $ .ajax à partir de la fonction GetHours - comme ceci:

function GetHours() {
$.ajax({
    url: "/api/tst/GetMyData",
    type: 'GET',
    dataType: 'json',

    success: function(data) {
       return data;
    },

    error: function(data) {
        return 0;
    }
});

};

0
Adam