Как мне отправить в EventListener из вложенной функции в Node.js (проблема с JavaScript) - PullRequest
2 голосов
/ 09 марта 2012

Я пишу код ниже, который анализирует API сайтов по одному, а затем сообщает очереди событий, что она готова для анализа следующего объекта.У меня возникли проблемы, так как я все еще новичок в области видимости javascript и хотел бы получить из SiteParser или вызвать функцию emitForNext.Я не могу принести emitForNext в область в обратном вызове ошибки.

   function SiteParser(){
        this.emitForNext = function  (message) {
            this.emit("next", message);
        };

        this.pullJSON = function (path, processJSON) { //processJSON is a callback function    
            var options = {
                host: 'www.site.com',
                port: 80,
                path: path
            }

            //console.log("... processing "+path); 

            //pulls the entire json request via chunks
            http.get(options, function  (res) {
                var resJSON = ''; //stores the comment JSON stream given in the res
                res.on('data',  function (chunk) {
                    resJSON+=chunk;   
                });  
                res.on('end', function () {
                    var obJSON = (JSON.parse(resJSON));  

                    if (obJSON.hasOwnProperty("error")){ 
                        console.log(obJSON);
                        console.log('... ', path, ' does not exist');
                        //
                        //NEED A NEXT EVENT EMMITER HERE NEED TO FIGURE OUT SCOPE
                        //
                        //   
                    } else {
                        processJSON(obJSON); //call the callback function
                    }
                }) ;
            }).on('error', function  (e) {
                emitForNext("got error: " + e.message);
            });
        };
    }

Ответы [ 3 ]

4 голосов
/ 09 марта 2012

JavaScript имеет область видимости функции, если вы объявите переменную с ключевым словом var, она будет локальной для текущей функции.Когда вы обращаетесь к переменной, она просматривает цепочку областей видимости, которая состоит из текущей функции, ее родительской функции,….Попробуйте:

function one() {
    var foo = 'foo';

    function two() {
        console.log(foo) // undefined. I'll explain this
        var foo = 'bar';
        console.log(foo) // bar
    }

    two()
    console.log(foo) // foo
}
one()

Большую часть времени мы определяем переменные в начале функций, потому что переменная, определенная в теле функции, поднимается.По сути, это означает, что она доступна во всей функции, даже до ее определения, но в этом случае ее значение равно undefined.

Например, если переменная не определена, мы обычно получаем ReferenceError, нов приведенном ниже фрагменте кода оба console.log() просто печатают undefined.

function foo() {
     console.log(bar);
     if (0) {
         var bar = 'bar';
     }
     console.log(bar);
}

Итак, обычная практика заключается в том, что когда вы пишете длинные функции, вы отображаете это на себя.

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

Собирая все это вместе, я написал бы:

var SiteParser = function() {};

SiteParser.prototype.emitForNext = function(message) {
    this.emit("next", message);
};

SiteParser.prototype.pullJSON = function(path, processJSON) { 
    var self    = this,
        options = {
            host: 'www.site.com',
            port: 80,
            path: path
        };

    http.get(options, function(res) {
        // ...
    }).on('error', function  (e) {
        self.emitForNext("got error: " + e.message);
    });
};
2 голосов
/ 09 марта 2012

Чтобы получить доступ к emitForNext, вам нужно вызвать self.emitForNext, где self указывает на ваш экземпляр SiteParser.

Примерно так:

function SiteParser(){

    this.emitForNext = function  (message) {

        this.emit("next", message);

    };



    this.pullJSON = function (path, processJSON) { //processJSON is a callback function    

        var options = {

            host: 'www.site.com',

            port: 80,

            path: path

        };



        var self = this;



        //console.log("... processing "+path); 



        //pulls the entire json request via chunks

        http.get(options, function  (res) {

            var resJSON = ''; //stores the comment JSON stream given in the res

            res.on('data',  function (chunk) {

                resJSON+=chunk;   

            });  

            res.on('end', function () {

                var obJSON = (JSON.parse(resJSON));  



                if (obJSON.hasOwnProperty("error")){ 

                    console.log(obJSON);

                    console.log('... ', path, ' does not exist');





                    self.emitForNext(path + ' does not exist');

                } else {

                    self.emitForNext('Successfully parsed the response');

                    processJSON(obJSON); //call the callback function

                }

            }) ;

        }).on('error', function  (e) {

            self.emitForNext("got error: " + e.message);

        });

    };

}

Однако этоПохоже, вы бы предпочли управлять тем, что вы будете делать дальше (например, анализировать следующий объект) в вашем обратном вызове, т.е.в теле processJSON.

1 голос
/ 09 марта 2012

Вам необходимо сохранить ссылку на объект this в локальной области SiteParser.

 function SiteParser () {
    var that = this; // store link to 'this' in local scope

    this.emitForNext = function (message) {
        this.emit("next", message);
    };

    this.pullJSON = function (path, processJSON) { //processJSON is a callback function    
        var options = {
            host: 'www.site.com',
            port: 80,
            path: path
        }

        //console.log("... processing "+path); 

        //pulls the entire json request via chunks
        http.get(options, function  (res) {
            var resJSON = ''; //stores the comment JSON stream given in the res
            res.on('data',  function (chunk) {
                resJSON+=chunk;   
            });  
            res.on('end', function () {
                var obJSON = (JSON.parse(resJSON));  

                if (obJSON.hasOwnProperty("error")){ 
                    console.log(obJSON);
                    console.log('... ', path, ' does not exist');
                    that.emitForNext();
                } else {
                    processJSON(obJSON); //call the callback function
                }
            }) ;
        }).on('error', function (e) {
            that.emitForNext("got error: " + e.message);
        });
    };
}
...