Je découvre le concept "d'objets" en JavaScript. Je fais un analyseur RSS et j'ai une erreur (commentée).

function MyParser (feed_url) {  // Construct
    "use strict";
    this.feedUrl = feed_url;
    this.pubArray = [];

    if (typeof (this.init_ok) == 'undefined') {
        MyParser.prototype.parse = function () {
        "use strict";
        var thisObj = this;
        $.get(this.feedUrl, function (data, textStatus, jqXHR) {
            if (textStatus == 'success') {
                var xml = jqXHR.responseXML,
                    //lastBuildDate = new Date($(xml).find('lastBuildDate').text());
                    items = $(xml).find('item');
                items.each(function () {
                    var pubSingle = thisObj.makeObj($(this).find('pubDate').text(),
                                                    $(this).find('link').text(),
                                                    $(this).find('title').text(),
                                                    $(this).find('description').text(),
                                                    $(this).find('encoded').text(),
                                                    $(this).find('commentRss').text(),
                                                    $(this).find('comments').last().text());
                    thisObj.pubArray.push(pubSingle);
                });
                console.log(thisObj.pubArray); // OK
            }
        }, 'xml');
        console.log(this.pubArray); // Empty
        return (this.pubArray);
    };

    MyParser.prototype.makeObj = function (pubDate, pubLink, pubTitle, pubDesc, pubContent, pubComCount, pubComLink) {
        "use strict";
        var pubSingle = {};
        pubSingle.pubDate = new Date(pubDate);
        pubSingle.pubLink = pubLink;
        pubSingle.pubTitle = pubTitle;
        pubSingle.pubDesc = pubDesc;
        pubSingle.pubContent = pubContent;
        pubSingle.pubComCount = pubComCount;
        pubSingle.pubComLink = pubComLink;
        return (pubSingle);
    };
}
this.init_ok = true;
}

Si vous regardez le console.log(), vous verrez que la ligne // OK sort correctement mon tableau.

Mais plus tard, au retour de $.get, mon tableau est vide.

Quelqu'un at-il une idée pourquoi et comment corriger cela s'il vous plaît?

2
Max13 16 déc. 2011 à 16:20

3 réponses

Meilleure réponse

Ce n'est pas un problème avec la portée variable. Le problème ici est que vous travaillez avec un flux asynchrone et que vous ne pensez pas correctement au flux.

Laissez-moi expliquer:

Lorsque vous effectuez votre .get, vous déclenchez un processus asynchrone parallèle qui demandera des informations au navigateur, mais le flux de votre programme principal continue, donc lorsque vous arrivez à votre instruction "return", votre tableau a pas encore rempli avec la réponse de votre méthode get.

Vous devez utiliser votre tableau à l'intérieur du rappel get et non à l'extérieur, car vous ne pouvez pas garantir que le tableau contiendra les informations dont vous avez besoin.

Celà a-t-il un sens?

Faites le moi savoir!

Plus d'explications

Selon vos commentaires, vous faites toujours quelque chose comme ça:

Var results = MyParser (feed_url); // code qui utilise results.pubArray

Et vous ne pouvez pas faire ça. Même si vous définissez votre "pubArray" dans votre .get rappel, vous essayez d'utiliser pubArray juste après avoir appelé MyParser et c'est avant que le .get rappel ne soit appelé. Ce que vous devez faire, c'est appeler votre prochaine étape sur la logique de votre programme depuis le .get rappel ... c'est la seule façon d'être sûr que le pubArray est rempli de données appropriées.

J'espère que cela le rend plus clair.

4
Deleteman 18 déc. 2011 à 02:44

Merci à tous et particulièrement à @Deleteman.

Voici ce que j'ai fait:

$.get(this.feedUrl, 'xml').success(function () {
    thisObj.handleAjax(arguments[0], arguments[1], arguments[2]);
    $(document).trigger('MyParserDone');
}).error(function () {
    $(document).trigger('MyParserFailed');
});

Ensuite, lorsque j'entre «HandleAjax», je suis de retour dans mon contexte d'objet, donc «ceci» fait référence à mon objet et aux bonnes propriétés. Le seul "problème" est que je dois définir un écouteur (MyParserDone) pour m'assurer que l'analyse est terminée.

0
Max13 19 déc. 2011 à 10:58

C'est parce que votre ligne

 console.log(this.pubArray); // Empty

Est appelé directement après avoir émis votre demande Ajax; il n'a pas encore eu le temps de récupérer les données. La ligne

console.log(thisObj.pubArray); // OK

Est appelé dans le rappel Ajax, date à laquelle les données ont été récupérées.

3
Graham 16 déc. 2011 à 12:26