简体   繁体   中英

Data Stream and Promises Node.js with serialport

I am working on a nodejs project that utilizes a serial port for communicating with a microcontroller. I can get everything to work using serialport but I'm struggling to determine the best method for handling received data.

Here's the basic program I'm testing with:

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;
}

I would like to return a promise that will be fulfilled once data has been received. Currently I'm emitting an event and using a listener to fulfill the promise. Is this the best method or is there a better option?

UPDATE

I plan to export a function for writing to the serial port that fulfills a promise once data is received.

Example:

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

For something that streams an arbitrary amount of data (ie, the parser object may have many data events), you probably don't want to use a promise. Once a promise is resolved, it is resolved for good (ie, you can only put data into it once -- which it looks like you know by the way you have set up readAsync ). You might want to instead try something called an Observable. You can connect the observable to the stream in question and it will queue them up for later transformations or use (you can think of it as a promise that can accept multiple data items). Here is a good SO answer explaining how streams (what you are currently with) and observables can interoperate for more programmatic flexibility.

Unfortunately, Node.js does not have an Observable utility built-in, but there is a canonical and battle-tested solution, RxJS .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM