我目前正在使用node-serialport模块进行串口通信。我将发送一个命令ATEC,它将以ECHO响应。
然而,这个发送和接收数据的过程是异步的(在我发送数据之后,我将不知道数据何时会到达data事件),示例代码如下:
//Register the data event from the serial port
port.on('data', (data) => {
console.log(data);
});
//Send data using serialport
port.write('ATEC');有没有什么我可以这样写的?
//When i send the command, I could receive the data
port.write('ATEC').then((data)=> {
console.log(data);
});这有可能实现吗?
在使用request客户端进行http通信时,我们可以这样做
request.get('http:\\google.com')
.on('response', (res) => {
console.log(res);
});我想使用serialport复制相同的行为
发布于 2016-07-11 08:24:09
在我正在做的一个项目中,我们遇到了类似的问题。需要一个用于串行的同步发送/接收循环,而serialport包让这变得有点奇怪。
我们的解决方案是让串口"data“事件服务的函数/promises/generators/等(取决于您的架构)的某种类型的队列。每次你写东西的时候,把一个函数/promise/等放入队列。
让我们假设您只是将函数抛入队列中。当" data“事件被触发时,它将当前聚合的接收缓冲区作为参数发送到队列的第一个元素中,该元素可以查看它是否包含它需要的所有数据,如果包含,则对其执行某些操作,并以某种方式将其从队列中删除。
这允许您使用相同的基本机制来处理多种不同类型的架构(回调/承诺/协程/等等)。
额外的好处是:如果您完全控制了协议的两端,您可以在这些字符串的末尾添加一个"\n“,然后使用serialport的"readline”解析器,这样您就只能获得整个字符串上的数据事件。如果输入是分片的,可能会让事情变得比不断检查输入的有效性容易一些。
更新:
现在,代码已经完成并进行了测试(请参阅http://github.com/metafetish/buttshock-js中的ET312模块),下面是我如何做的:
function writeAndExpect(data, length) {
return new Promise((resolve, reject) => {
const buffer = new Buffer(length);
this._port.write(data, (error) => {
if (error) {
reject(error);
return;
}
});
let offset = 0;
let handler = (d) => {
try {
Uint8Array.from(d).forEach(byte => buffer.writeUInt8(byte, offset));
offset += d.length;
} catch (err) {
reject(err);
return;
}
if (offset === length) {
resolve(buffer);
this._port.removeListener("data", handler);
};
};
this._port.on("data", handler);
});
}上面的函数接受一个uint8s列表,并返回一个预期的数据量,返回一个promise。我们写入数据,然后将自己设置为" data“事件处理程序。我们使用它来读取,直到我们获得我们期望的数据量,然后解析promise,删除自己作为“数据”侦听器(这是重要的,否则您将堆叠处理程序!),并完成。
这段代码非常符合我的需要,除了使用已知参数非常严格的发送/接收对之外,它不会处理其他情况,但它可能会给您一个开始的想法。
发布于 2016-07-11 09:22:15
我在串行数据接收中包装了一个承诺
function sendSync(port, src) {
return new Promise((resolve, reject) => {
port.write(src);
port.once('data', (data) => {
resolve(data.toString());
});
port.once('error', (err) => {
reject(err);
});
});
}请注意,事件正在使用once而不是on来防止事件堆叠(请查看下面的评论以了解更多信息-感谢@DKebler发现它)
然后,我可以同步编写代码,如下所示
sendSync(port, 'AThello\n').then((data) => {
//receive data
});
sendSync(port, 'ATecho\n').then((data) => {
//receive data
});或者我可以使用一个生成器,使用co包
co(function* () {
const echo = yield sendSync(port, 'echo\n');
const hello = yield sendSync(port, 'hello 123\n');
return [echo, hello]
}).then((result) => {
console.log(result)
}).catch((err) => {
console.error(err);
})https://stackoverflow.com/questions/37739992
复制相似问题