【问题标题】:Node.js Cannot read property 'on' of undefinedNode.js 无法读取未定义的属性“on”
【发布时间】:2016-05-09 02:08:46
【问题描述】:

怎么了?

附言: 我是 node.js 的新手,我来自 .Net 世界!

我的 server.js 代码:

    var events = require('events').EventEmitter;
    var v = function() {
        var e = new events();
        e.emit('start');
    };

    var r = v();
    r.on('start', function(){
        console.log('event start just fired!!!!!!!!!!');
    });

这个控制台输出:

TypeError: Cannot read property 'on' of undefined
    at Object.<anonymous> (E:\Project\node\BasicSocial\server.js:12:2)
    at Module._compile (module.js:410:26)
    at Object.Module._extensions..js (module.js:417:10)
    at Module.load (module.js:344:32)
    at Function.Module._load (module.js:301:12)
    at Function.Module.runMain (module.js:442:10)
    at startup (node.js:136:18)
    at node.js:966:3

【问题讨论】:

    标签: javascript node.js events dom-events


    【解决方案1】:

    您忘记从 v 函数返回事件发射器:

    var v = function() {
        var e = new events();
        e.emit('start');
        return e;
    };
    

    还要注意start 事件不会被调用,因为您在订阅它之前已经发出了该事件。所以你可以稍微修改一下你的代码:

    var events = require('events').EventEmitter;
    var v = function() {
        var e = new events();
        return e;
    };
    
    var r = v();
    r.on('start', function(){
        console.log('event start just fired!!!!!!!!!!');
    });
    
    // emit the event after you have subscribed to the start callback
    r.emit('start');
    

    【讨论】:

    • 虽然不会引发错误,但不会触发 on("start"),因为在绑定 on 时已经发出了事件。
    • 那么在我们能够控制之前这么快就触发了这个事件有什么用呢?
    • 它的发射速度不快。当您(在您的代码中)使用 event() 函数显式触发它时,它就会触发。因此,请确保您订阅了该活动之后这样做。所以基本上你可以完全控制正在发生的事情。首先你应该确保订阅者已经配置好,然后触发事件。
    • 哦,我知道我什么时候使用 r = v();我触发了自己的事件,然后由我的 .on 事件处理程序处理。
    • 是的,这正是您原始代码的两个问题之一。
    【解决方案2】:

    r 未定义,因为v 没有返回任何内容。这就是您收到错误的原因。即使你返回事件,你的代码也不会给你想要的输出,因为你需要在使用emit("start")之前使用on("start")

    var events = require('events').EventEmitter;
    
    var e = new events();
    
    e.emit('start'); //This won't trigger the console.log
    
    //Need to be binded before you emit the event.
    e.on('start', function(){
        console.log('event start just fired!!!!!!!!!!');
    });
    
    e.emit('start'); //This will trigger the console.log
    

    【讨论】:

      【解决方案3】:

      您也可以使用Process.nextTick()setTimeout(yourFunction,0)

      当您发出和使用回调函数时,这两个函数会派上用场。

      在这里,使用nextTick 函数,我可以将函数推送到事件循环中,该函数将在调用堆栈中的所有进程都执行完毕后执行。

      var EventEmitter = require('events').EventEmitter;
      
      var getValue = function(val){
          var e = new EventEmitter();
          process.nextTick(function(){
              var c = 0;
              e.emit('Start');
              var t = setInterval(function(){
                  e.emit('Processing data', ++c);
                  if(c==val){
                      e.emit('Stopped',c);
                      clearInterval(t);
      
                  }
              },10);
      
          });
          return e;
      }
      
      var r = getValue(7);
      
      r.on('Start', function(){
          console.log("Started");
      });
      
      r.on('Processing data', function(d){
          console.log('Data '+d);
      });
      
      r.on('Stopped', function(d){
          console.log('Stopped '+d)
      });
      

      【讨论】:

      • 请添加更多细节好​​友。 OP说他是新手。如果您对建议的解决方案有更多的了解,那就更好了。
      • 添加了一个例子。 :)
      【解决方案4】:

      在创建事件对象之前你必须忘记写新

      const events=require("events");
      const event=***new*** events.EventEmitter();
      event.on('click' ,() => console.log("hello"));
      event.emit('click');
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-06-15
        • 2018-12-17
        • 2016-06-30
        • 2017-03-24
        • 1970-01-01
        • 1970-01-01
        • 2021-12-05
        相关资源
        最近更新 更多