Область видимости переменной в объекте Javascript - PullRequest
2 голосов
/ 16 декабря 2011

Я открываю для себя понятие «объекты» в JavaScript.Я делаю парсер RSS, и у меня есть ошибка (закомментировано).

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;
}

Если вы посмотрите на console.log(), вы увидите, что строка // OK правильно выводит мой массив.

Но позже, при возврате из $.get, мой массив пуст.

У кого-нибудь есть идеи, почему и как это исправить, пожалуйста?

Ответы [ 3 ]

4 голосов
/ 16 декабря 2011

Это не проблема с переменной областью действия.Проблема здесь в том, что вы работаете с асинхронным потоком и не правильно думаете о потоке.

Позвольте мне объяснить:

Когда вы делаете .get, вы запускаете параллельасинхронный процесс, который будет запрашивать информацию из браузера, но поток вашей основной программы будет продолжаться, поэтому, когда вы попадете в оператор "return", ваш массив еще не был заполнен ответом от вашего метода get.

Вы должны использовать свой массив изнутри обратного вызова get, а не вне его, поскольку вы не можете гарантировать, что массив будет иметь необходимую информацию.

Имеет ли это какой-то смысл?

Дайте мне знать!

Дальнейшее объяснение

Согласно вашим комментариям, вы все еще делаете что-то вроде этого:

var results = MyParser(FEED_URL);// код, который использует results.pubArray

И вы не можете этого сделать.Даже если вы устанавливаете свой pubArray внутри обратного вызова .get, вы пытаетесь использовать pubArray сразу после вызова MyParser, и это до вызова обратного вызова .get.Что вам нужно сделать, так это вызвать следующий шаг в логике вашей программы из обратного вызова .get ... это единственный способ убедиться, что pubArray заполнен правильными данными.

Я надеюсь, что это проясняет ситуацию.

3 голосов
/ 16 декабря 2011

Это потому, что ваша линия

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

вызывается сразу после того, как вы отправили Ajax-запрос; он еще не успел получить данные. Линия

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

вызывается внутри функции обратного вызова Ajax, к которой данные извлекаются.

0 голосов
/ 19 декабря 2011

Спасибо всем, и в особенности @Deleteman.

Вот что я сделал:

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

Затем, когда я ввожу "HandleAjax", я снова в контексте моего объектатак что «это» относится к моему объекту и нужным свойствам.Единственная «проблема» заключается в том, что мне нужно установить прослушиватель (MyParserDone), чтобы убедиться, что анализ завершен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...