数据流与Promises:使用serialport在Node.js中的应用

4

我正在开发一个使用串口与微控制器通信的nodejs项目。我可以使用serialport使一切正常工作,但我在确定处理接收到数据的最佳方法方面遇到了困难。

下面是我正在测试的基本程序:

const serialPort = require('serialport');
const delimiter = require('@serialport/parser-delimiter')

const readline = require('readline');
const EventEmitter = require('events');

const rl = readline.createInterface({
  input: process.stdin, 
  output: process.stdout
});

rl.setPrompt('> ');
rl.prompt();

const uart = new serialPort('path-to-port', {
  baudRate: 9600
});

const parser = uart.pipe(new delimiter({ delimiter: '\n'}));

const event = new EventEmitter();

parser.on('data', (data) => {
  event.emit('dataReady', data);
});

rl.on('line', (input) => {
  if(input === 'close'){
    console.log('Bye');
    process.exit();
  }

  uart.write(input + '\n', (err) => {
    if (err) {
      console.log('uart write error');
    }
  });

  console.log('Waiting on data...');
  readAsync().then((data) => {
    console.log(' ->', data.toString());
    rl.prompt();
  });


});

const readAsync = () => {
  const promise = new Promise((resolve, reject) => {
    event.once('dataReady', (data) => {
      resolve(data);
    });
  });

  return promise;
}

我希望返回一个承诺,一旦收到数据就会被实现。 目前我正在发出事件并使用侦听器来实现承诺。 这是最好的方法还是有更好的选择?
更新
我计划导出一个写入串行端口的函数,一旦收到数据就会实现一个承诺。
例如:
module.exports.write = (cmd) => {
  uart.write(input + '\n', (err) => {
    if (err) {
      console.log('uart write error');
    }
  });
  return readAsync();
}
1个回答

1

对于流式传输任意数量的数据(即,parser对象可能有很多data事件),您可能不想使用promise。一旦promise被解决,它就会永久解决(即,您只能将数据放入其中一次--这看起来像是您已经设置了readAsync的方式)。您可能希望尝试称为Observable的东西。您可以将可观察对象连接到相关的流中,并将其排队以进行后续转换或使用(您可以将其视为可以接受多个数据项的promise)。这里有一个好的SO答案,解释了流(您当前正在使用的内容)和可观察对象如何相互操作以获得更多的编程灵活性。

不幸的是,Node.js没有内置的Observable实用程序,但有一个经典而经过验证的解决方案,RxJS


有趣的是,我之前不知道 Observables。没有数据被发送之前不应该接收到任何数据。基本上,我发送一个命令并接收一个响应。由于接收到的数据在已知时间内,我是否应该坚持单个事件?请查看我的更新以了解我的预期用例。 - Dillon Wiggins
如果你只是来回传递数据,你可能只需要使用 Promise,但我想确认一下,在单个“write”事件后,你不可能收到多个“data”事件。如果这种情况发生,你会想要将所有这些数据事件缓存在一起,对吧?然后只有在所有数据都被读取后才解析 Promise。 - Jclangst
仔细看了一下,即使乒乓球可以工作,根据我在您的代码中看到的所有内容,我敢打赌您仍然想使用Observables来利用“反应”范例。您会对每个接收到的换行符做出反应(打印到控制台,执行操作等)。 - Jclangst
是的,我不应该在意料之外的时间接收数据。我会格式化来自MCU的数据,以便可以添加广播数据和响应数据的标志,然后在解析器的on data中分别处理它们。谢谢! - Dillon Wiggins
我将致力于实现Observables并查看性能和可靠性是否有所不同。学习新知识总是很好的。感谢您的输入。 - Dillon Wiggins

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接