Node.js模块 - 事件发射器



我正在尝试为 Raspberry Pi 的 GPIO-Pins 创建自己的模块,但如果有什么变化(例如按下/释放按钮),我想接收.on('something', function() { })事件。

python 脚本每 0.01 秒发送一次值,如 true 或 false。

模块.js

var PythonShell = require('python-shell');
module.exports = {
     switch_live: function(pin) {
         var status = false;
         this.get = (function(){
             return status;
         });
         var options = {
             mode: 'text',
             args: [pin],
             pythonOptions: ['-u']
         };
         var pyshell = new PythonShell('./data/switch_loop.py', options);
         pyshell.on('message', function(message) {
             if (message == 'false') {
                 if (status) {
                     // EMIT: button released
                 }
                 status = false;
             } else {
                 if (!status) {
                     // EMIT: button pressed
                 }
                 status = true;
             }

         });
         return this.status;       
    },
    some_other_funcs: function(pin) {
        // ...
    }
}

应用.js

var module = require('./module.js');
var button = new module.switch_live(10);

该模块可以显示按钮的状态:

// get status of button
var status = button.get(); // returns "true" or "false"

但我想要这样的东西:

button.on('pressed', function() {
    // call this function every time when button is pressed
});
button.on('released', function() {
    // call this function every time when button is released
});

谢谢:)

编辑:我没有找到解决方案,因为我需要"模块导出"中的函数。

我的解决方案

它是用于Linkerkit-Board的模块。

应用.js

var linkerkit = require('./linkerkit.js');
var button = new linkerkit.switch_live(20);
button.on('pressed', function() {
  // call this function every time when button is pressed
    console.log('press');
});
button.on('released', function() {
  // call this function every time when button is released
    console.log('release');
});

链接套件.js

var PythonShell = require('python-shell');
var EventEmitter = require('events');
var util = require('util');
var linkerkit = {
    switch_live: function(pin) {
        var self = this;
        this.status = false;
        this.pin = pin;
        EventEmitter.call(this);
        this.get = function() {
            return this.status;
        }
        this._pyshell = new PythonShell('./data/switch_loop.py', {
            mode: 'text', 
            args: [this.pin], 
            pythonOptions: ['-u']
        });
        this._pyshell.on("message", function(message) {
            if (message === "false") {
                if (this.status === true) {
                    // EMIT: button released
                    self.emit("released");
                }
                this.status = false;
            }
            else {
                if (this.status === false) {
                    // EMIT: button pressed
                    self.emit("pressed");
                }
                this.status = true;
            }
        });
    }
}

for (var key in linkerkit) {
    util.inherits(linkerkit[key], EventEmitter);
}
module.exports = linkerkit;

我编辑了代码,因为它应该能够做这样的事情:

var button = linkerkit.switch(20);
button.get() // get status of button once, has no python loop
var button_live = linkerkit.switch_live(20);
button.get() // get status of button once, has a python loop
button.on('pressed', callback);
button.on('released', callback);
var led = linkerkit.led(10);
led.on();
led.off();
led.brightness(255); // digitalOutput - brightness
led.blink(200); // 100ms on, 100ms off
var ledcolor = linkerkit.led_rgb(12);
ledcolor.on(); // on -> color: white
ledcolor.off(); 
ledcolor.rgb([255, 0, 0]); // on -> color: red

还有更多功能...

你应该能够使用 Node 的内置EventEmitter类来创建你自己的"按钮发射器":

模块.js

var PythonShell = require('python-shell');
var util = require('util');
var EventEmitter = require('events');
function ButtonEmitter(pinNumber) {
  this.status = false;
  this.pinNumber = pinNumber;
  EventEmitter.call(this);
}
util.inherits(ButtonEmitter, EventEmitter);
ButtonEmitter.prototype.get = function() {
  return this.status;
};
ButtonEmitter.prototype.switch_live = function() {
  var options = {
    mode: 'text',
    args: [this.pinNumber],
    pythonOptions: ['-u']
  };
  this._pyshell = new PythonShell('./data/switch_loop.py', options);
  this._pyshell.on("message", this._handleMessage.bind(this));
  return this.status;
};
ButtonEmitter.prototype._handleMessage = function(message) {
  if (message === "false") {
    if (this.status === true) {
      // EMIT: button released
      this.emit("pressed");
    }
    this.status = false;
  } else {
    if (this.status === false) {
     // EMIT: button pressed
     this.emit("released");
    }
    this.status = true;
  }
};
module.exports = ButtonEmitter;

应用.js

var ButtonTrigger = require('./module.js');
var button = new ButtonTrigger(10);
button.on('pressed', function() {
  // call this function every time when button is pressed
});
button.on('released', function() {
  // call this function every time when button is released
});
button.swith_live();

解释

上面的代码利用了 Node 对"子类"EventEmitter util.inherits,以便任何使用你的类的人都可以访问.on().off()和其他事件方法。(注意:如果你的 Node 版本支持它,你也可以使用 ES6 classextends语法)

然后,使用"子类",添加自己的switch_live方法来启动"侦听"过程,并向其传递_handleMessage回调。

_handleMessage回调运行时,它会将当前状态与传入状态进行比较,并使用您在问题中发布的事件名称触发.emit()。同样,.emit()可用是因为您是一个"子类化"EventEmitter

最新更新