我是nodejs的新手,并试图通过重建现有的i2c传感器系统来学习基础知识。
使用命名函数和async.series在单个文件中使所有文件都运行。为了保持可重用性,我现在想创建一个我可以导入的类。不幸的是,我遇到了一些我不明白的错误。
class.js
const async = require('async');
const i2c = require('i2c-bus');
class Sensor {
constructor (channel) {
this.channel = channel;
var self = this;
}
openBus (callback) {
bus = i2c.open(self.channel, (err) => {callback()}); // shorted for stackoverflow
}
closeBus (callback) {
bus.close( (err) => {callback()}); //also shorted for better readability
}
connection (callback) {
/* first variation */
async.series([openBus, closeBus], callback);
connection2 (callback) {
/* second variation */
async.series([this.openBus, this.closeBus], callback);
}
}
module.exports = K30;
当我导入类时,我可以毫无问题地创建一个新的传感器“对象”并直接使用以下函数调用函数:
> var Sensor = require('./class.js');
> var mySensor = new Sensor(1);
> mySensor.openBus(foo);
> mySensor.closeBus(bar);
但是如果我尝试调用包装函数,则会出现以下错误:
> mySensor.connection(foo);
ReferenceError: openBus is not defined (at 'connection')
> mySensor.connection2(foo);
ReferenceError: self is not defined (at 'openBus')
我相信这些错误的发生是由于我缺乏对正确的用法的理解。可悲的是我找不到关于这个话题的好消息。任何帮助都将受到高度赞赏。
更新
实际上,前两个解决方案中提供的解决方案是我在开始使用“自我”之前的第一个方法(经过一些[this-that-trick]搜寻之后)。
无论如何,这是我使用“ this.channel”代替的输出/错误:
> mySensor.connection2(foo);
TypeError: Cannot read property 'channel' of undefined (at openBus)
答案 0 :(得分:0)
此内容不会保存在var self = this;
的任何位置,因此在函数(构造函数为function)结束时会丢失。
只需删除构造函数中的上述行,并在各处使用this
而不是self
。
在JavaScript中,this
关键字确实有点棘手,但是如果您采用合理的方法,那应该没事。
答案 1 :(得分:0)
您确实对this
和self
有疑问
该类中的每个成员都必须由this
进行引用。如果您声明了一个名为var EBZ-Krisemendt = "SO user";
的变量,则需要使用它,例如:console.log(this.EBZ-Krisemendt);
您需要的是
openBus (callback) {
bus = i2c.open(this.channel, (err) => {callback()});
}
然后mysensor.connection2(foo)
可以正常工作。
答案 2 :(得分:0)
虽然我仍然不完全了解其背后的原因,但我通过摆脱“ ES6”类定义来修复了代码。
class.js
const i2c = require('i2c-bus');
const async = require('async');
function Sensor(channel) {
let that = this; // make 'this' available in sub-function scope
this.channel = channel;
function openBus(cb) {
// open the bus-connection
bus = i2c.open(that.channel);
}
function closeBus(cb) {
// close the bus-connection
}
function connection(cb) {
async.series([openBus, closeBus], cb);
}
function getReading(cb) {
async.until(
function() {
// loop condition e.g. max tries to get reading
},
function(cb) {
connection(cb); // calling nested synchronous connection-routine
},
function (err) {
// result handling
}
); // end async.until
} // end getReading
return {
getReading: getReading
} // make only 'getReading' available
}
module.exports = {
Sensor: Sensor
} // make 'Sensor' available
在“成员”功能中,我现在可以通过使用“ that”(例如:“ that.channel”)访问它们来使用“传感器”的“类”变量
详细信息:
function openBus(cb){
bus = i2c.open(that.channel);
}
如果我要使用 this 而不是 that ,则只能在直接调用 openBus 时才能使用。在我的示例中,有必要以同步方式(出于明显的原因)调用 openBus 和 closeBus 。由于 async.series 另外嵌套在 async.until 中(传感器可能需要多次尝试以进行响应),因此此的范围有所更改。通过使用 that ,我可以忽略范围。
评论: 由于解决方案通常指的是在自定义模块中使用嵌套的异步调用,因此我会稍微更改初始问题的名称。我仍然希望有更好的解决方案和/或解释,所以我不会将自己的答案标记为接受。