求Node.js中类似MS2的响应式自动刷新表格示例
实现带自动刷新的只读数据表格(基于Inquirer响应式接口)
核心思路
- 基于Inquirer的响应式API自定义只读表格Prompt,屏蔽输入交互,只做数据展示
- 支持两种刷新触发方式:
- 定时刷新:用
setInterval固定间隔重新渲染表格 - 数据变更触发刷新:通过定时对比数据快照,检测到变化时立即渲染
- 定时刷新:用
完整代码示例
先安装依赖:
npm install inquirer
const inquirer = require('inquirer'); // 自定义只读表格Prompt inquirer.registerPrompt('readonly-table', class extends inquirer.prompts.Prompt { constructor(questions, rl, answers) { super(questions, rl, answers); this.data = this.opt.data || []; this.headers = this.opt.headers || []; this.refreshTimer = null; this.dataWatchTimer = null; this.lastDataSnapshot = JSON.stringify(this.data); // 定时刷新逻辑 if (this.opt.refreshInterval) { this.refreshTimer = setInterval(() => this.render(), this.opt.refreshInterval); } // 数据变更监听(定时对比数据快照) if (this.opt.watchData) { this.dataWatchTimer = setInterval(() => { const currentSnapshot = JSON.stringify(this.data); if (currentSnapshot !== this.lastDataSnapshot) { this.lastDataSnapshot = currentSnapshot; this.render(); } }, 100); // 监听频率可按需调整 } } // 渲染表格到终端 render() { this.screen.render(this.buildTableString()); // 只读模式:直接返回Promise.resolve维持响应式循环 return Promise.resolve(); } // 构建纯字符表格 buildTableString() { let output = '\n'; // 打印表头 output += `| ${this.headers.map(h => h.padEnd(18)).join(' | ')} |\n`; output += `| ${this.headers.map(() => '-'.repeat(18)).join(' | ')} |\n`; // 打印数据行 this.data.forEach(row => { output += `| ${row.map(cell => String(cell).padEnd(18)).join(' | ')} |\n`; }); output += '\nPress Ctrl+C to exit\n'; return output; } // 清理定时器避免内存泄漏 close() { if (this.refreshTimer) clearInterval(this.refreshTimer); if (this.dataWatchTimer) clearInterval(this.dataWatchTimer); super.close(); } }); // 模拟业务场景:动态数据+自动刷新 async function startTable() { // 初始化表格数据 let tableRows = [ [1, 'User Service', 'Online', new Date().toLocaleTimeString()], [2, 'Payment Service', 'Online', new Date().toLocaleTimeString()], [3, 'Auth Service', 'Offline', new Date().toLocaleTimeString()] ]; const tableHeaders = ['ID', 'Service Name', 'Status', 'Last Updated']; // 模拟数据自动变更(每2秒随机修改一行状态和时间) setInterval(() => { const randomIndex = Math.floor(Math.random() * tableRows.length); tableRows[randomIndex][2] = Math.random() > 0.6 ? 'Online' : 'Offline'; tableRows[randomIndex][3] = new Date().toLocaleTimeString(); }, 2000); // 启动表格 await inquirer.prompt([ { type: 'readonly-table', name: 'serviceStatusTable', headers: tableHeaders, data: tableRows, refreshInterval: 1000, // 每秒强制刷新一次 watchData: true // 开启数据变更监听 } ]); } startTable().catch(err => console.error(err));
关键细节说明
- 自定义Prompt继承了Inquirer的
Prompt类,利用其screen.render方法实现终端内容更新 padEnd(18)用来统一列宽,可根据实际数据长度调整- 两种刷新模式可以单独或同时启用:定时刷新保证界面实时性,数据监听减少不必要的渲染
- 关闭时清理定时器,避免程序退出后残留后台进程
内容的提问来源于stack exchange,提问作者J. Pablo García
相关产品推荐
相关产品推荐

