使用async.series和async.until

时间:2018-07-13 11:43:24

标签: node.js async.js

我是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)

3 个答案:

答案 0 :(得分:0)

此内容不会保存在var self = this;的任何位置,因此在函数(构造函数为function)结束时会丢失。

只需删除构造函数中的上述行,并在各处使用this而不是self

在JavaScript中,this关键字确实有点棘手,但是如果您采用合理的方法,那应该没事。

答案 1 :(得分:0)

您确实对thisself有疑问

该类中的每个成员都必须由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 ,我可以忽略范围。

评论: 由于解决方案通常指的是在自定义模块中使用嵌套的异步调用,因此我会稍微更改初始问题的名称。我仍然希望有更好的解决方案和/或解释,所以我不会将自己的答案标记为接受。