上一篇介绍了 listr2 的安装和基本用法。本篇讲解一下,如何利用 listr2 任务的特性制作一个任务看板。
有时候我们需要在控制台持续显示某一个任务的执行状态,如监听一个串口,记录它收到了几次数据,这时我们可以使用 listr2 创建一个任务列表:
主要代码
index.ts:
ts
import { Listr, PRESET_TIMER } from "listr2";
import { analyser } from "./analyser";
import { dynamometer } from "./dynamometer";
const lists = new Listr(
[
{
title: "标定设备模拟",
task: (ctx, task) =>
task.newListr(
[
{
title: "模拟分析仪",
task: (ctx, task) =>
new Promise(() => {
analyser(str => {
task.title = "模拟分析仪:" + str;
});
}),
},
{
title: "模拟测功机",
task: (ctx, task) =>
new Promise(() => {
dynamometer(str => {
task.title = "模拟测功机:" + str;
});
}),
},
],
{
concurrent: true,
exitOnError: true,
rendererOptions: { collapseSubtasks: false },
}
),
},
],
{
exitOnError: true,
concurrent: false,
}
);
lists.run().catch(err => {
console.error(err);
});
分析以上代码,listr2 的任务接收一个返回 Promise 的函数,Promise 的状态控制 listr2 任务的完成状态,可以控制始终不执行 Promise 的 resolve 回调,这样任务就能一直保持运行状态。
同时,在执行任务过程中,可以修改task的标题,向用户传递信息,例如当前串口执行了多少次。
其余代码
其中 analyser 是模拟分析仪设备的,走 tcp 通信,包含接收数据和自动回复
dynamometer 是模拟测功机设备的,走串口通信,同样包含接收数据和自动回复
可以用以下代码模拟通信: analyser.ts
ts
import net from "net";
/**
* 模拟分析仪
*/
export function analyser(callback: (str: string) => void) {
const server = net.createServer(socket => {
callback("开始模拟");
let count = 0;
socket.on("data", data => {
socket.write(`1,2,${3 + ++count}`);
callback(`已收到数据,已自动回发数据 x${count}`);
});
socket.on("end", () => {
callback("连接结束");
});
socket.on("close", () => {
callback("连接关闭");
});
socket.addListener("error", err => {
callback("连接出错");
});
});
server.listen(9988, "127.0.0.1", () => {
callback(`分析仪运行在 http://127.0.0.1:9988/`);
});
}
dynamometer.ts
ts
import { SerialPort } from "serialport";
// 模拟测功机
export function dynamometer(callback: (str: string) => void) {
const serialPort = new SerialPort({
path: "COM5",
baudRate: 38400,
stopBits: 1,
parity: "none",
dataBits: 8,
autoOpen: true,
},() => {
callback(`模拟成功, 等待数据中`);
});
let count = 0;
// 接收到就回发
serialPort.on("data", data => {
callback(`收到串口数据 [${Array.from(data).toString()}], 稍后自动回发 x${++count}`);
setTimeout(() => {
serialPort.write(data);
callback(`回发串口数据 [${Array.from(data).toString()}] x${++count}`);
}, 1000);
});
}
效果演示
使用VSPD创建一对虚拟串口 COM5 和 COM6
上面的dynamometer.ts 监听了COM5 ,我们使用串口助手,向COM6 发送数据,用以观察效果,由于是一对虚拟串口,COM6 收到数据会自动发送给COM5
效果如下: