首页 > 解决方案 > 如何使用模块导出拉出处理程序?

问题描述

我正在构建一个节点应用程序,并试图整齐地组织我的代码。我编写了一个串行模块来导入串行库并处理连接。我的目的是编写一个基本模块,然后根据需要在不同的项目中一遍又一遍地重用它。每次使用都会改变的唯一部分是如何处理传入的串行数据。出于这个原因,我想提取以下处理程序并根据项目需要重新定义它。如何使用模块导出仅重新定义文件的这一部分?

我尝试添加myParser到导出中,但这给了我一个空值,我将超出范围。

为每个新项目重新定义/更改/重载的处理程序

myParser.on('data', (data) => {
    console.log(data)
    //DO SOMETHING WITH DATA
});

示例用法:main.js

const serial = require('./serial');
const dataParser = require('./dataParser');
const serial = require('./serial');

//call connect with CL args
serial.connect(process.argv[2], Number(process.argv[3]))

serial.myParser.on('data',(data) => {
   //Do something unique with data
    if (dataParser.parse(data) == 0)
       serial.send('Error');
});

serial.js下面的完整 JS 模块

const SerialPort = require('serialport');
const ReadLine = require('@serialport/parser-readline');
const _d = String.fromCharCode(13); //char EOL


let myPort = null;
let myParser = null;

function connect(port, baud) {
     let portName = port || `COM1`;
     let baudRate = baud || 115200;

     myPort = new SerialPort(portName, {baudRate: baudRate})
     myParser = myPort.pipe(new ReadLine({ delimiter: '\n'}))

     //Handlers
    myPort.on('open', () => {
        console.log(`port ${portName} open`)
    });

    myParser.on('data', (data) => {
        console.log(data)
    });

    myPort.on('close', () => {
        console.log(`port ${portName} closed`)
    });

    myPort.on('error', (err) => {
        console.error('port error: ' + err)
    });
}

function getPorts() {
    let portlist = [];
    SerialPort.list((err, ports) => {
        ports.forEach(port => {
            portlist.push(port.comName)
        });
    })
    return portlist;
}

function send(data) {
    myPort.write(JSON.stringify(data) + _d, function (err) {
        if (err) {
            return console.log('Error on write: ', err.message);
        }
        console.log(`${data} sent`);
    });
}

function close() {
    myPort.close();
}


module.exports = {
    connect, getPorts, send, close
}

标签: javascriptnode.jsmodule

解决方案


问题是在适合类或工厂的地方使用模块。myParser不被调用就不能存在connect,所以让它作为模块属性可用是没有意义的,默认情况下它是不可用的,并且多次connect调用会覆盖它。

它可以是一个工厂:

module.exports = function connect(port, baud) {
     let portName = port || `COM1`;
     let baudRate = baud || 115200;

     let myPort = new SerialPort(portName, {baudRate: baudRate})
     let myParser = myPort.pipe(new ReadLine({ delimiter: '\n'}))

     //Handlers
    myPort.on('open', () => {
        console.log(`port ${portName} open`)
    });

    myParser.on('data', (data) => {
        console.log(data)
    });

    myPort.on('close', () => {
        console.log(`port ${portName} closed`)
    });

    myPort.on('error', (err) => {
        console.error('port error: ' + err)
    });

    function getPorts() {
        let portlist = [];
        SerialPort.list((err, ports) => {
            ports.forEach(port => {
                portlist.push(port.comName)
            });
        })
        return portlist;
    }

    function send(data) {
        myPort.write(JSON.stringify(data) + _d, function (err) {
            if (err) {
                return console.log('Error on write: ', err.message);
            }
            console.log(`${data} sent`);
        });
    }

    function close() {
        myPort.close();
    }

    return {
        myParser, getPorts, send, close
    };
}

所以它可以像这样使用:

const serial = require('./serial');

const connection = serial(...);

connection.myParser.on('data',(data) => {
   //Do something unique with data
    if (dataParser.parse(data) == 0)
       connection.send('Error');
});

推荐阅读