🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# Readline ~~~ 稳定度: 2 - 不稳定 ~~~ 要使用此模块,需要`require('readline')`.Readline程序允许逐行读取一个流内容(例如`process.stdin`). 需要注意的是你一旦调用了这个模块,你的node程序将不会终止直到你关闭此接口。下面是如何让你的程序正常退出的方法: ~~~ rl.close(); }); ~~~ ### readline.createInterface(options) 创建一个readline的接口实例. 接受一个Object类型参数,可传递以下几个值: - `input` - 要监听的可读流 (必需). - `output` - 要写入 readline 的可写流 (必须). - `completer` - 用于 Tab 自动补全的可选函数。见下面使用的例子。 - `terminal` - 如果希望 `input` 和 `output` 流像 TTY 一样对待,那么传递参数 `true` ,并且经由 ANSI/VT100 转码。 默认情况下检查 `isTTY` 是否在 `output` 流上实例化。 通过用户 `completer` 函数给定了一个当前行入口,并且期望返回一个包含两个条目的数组: 1. 一个匹配当前输入补全的字符串数组. 1. 一个用于匹配的子字符串。 最终像这种形式: `[[substr1, substr2, ...], originalsubstring]`. 实例: ~~~ function completer(line) { var completions = '.help .error .exit .quit .q'.split(' ') var hits = completions.filter(function(c) { return c.indexOf(line) == 0 }) // show all completions if none found return [hits.length ? hits : completions, line] } ~~~ `completer` 也可以运行在异步模式下,此时接受两个参数: ~~~ function completer(linePartial, callback) { callback(null, [['123'], linePartial]); } ~~~ 为了接受用户的输入,`createInterface` 通常跟 `process.stdin` 和 `process.stdout` 一块使用: ~~~ var readline = require('readline'); var rl = readline.createInterface({ input: process.stdin, output: process.stdout }); ~~~ 一旦你有一个 readline 实例,你通常会监听 "line" 事件。 如果这个实例中`terminal`为`true`,而且`output`流定义了一个`output.columns`属性,那么`output`流将获得最好的兼容性,并且,当columns变化时(当它是TTY时,`process.stdout`会自动这样做),会在`output`上触发一个 `"resize"`事件。 ### 类: 接口 代表一个有输入输出流的 readline 接口的类。 ### rl.setPrompt(prompt) 设置提示符,例如当你在命令行运行 `node` 时,你会看到 `>` ,这就是 node 的提示符。 ### rl.prompt([preserveCursor]) 为用户输入准备好readline,将现有的`setPrompt`选项放到新的一行,让用户有一个新的地方开始输入。将`preserveCursor`设为`true`来防止光标位置被重新设定成`0`。 如果暂停,也会使用 `createInterface` 重置 `input` 流。 ### rl.question(query, callback) 预先提示指定的query,然后用户应答后触发指定的callback。 显示指定的query给用户后,当用户的应答被输入后,就触发了指定的callback 如果暂停,也会使用 `createInterface` 重置 `input` 流。 使用示例: ~~~ interface.question('What is your favorite food?', function(answer) { console.log('Oh, so your favorite food is ' + answer); }); ~~~ ### rl.pause() 暂停 readline 的输入流 (`input` stream), 如果有需要稍后还可以恢复。 ### rl.resume() 恢复 readline 的输入流 (`input` stream). ### rl.close() 关闭接口实例 (`Interface` instance), 放弃控制输入输出流。"close" 事件会被触发。 ### rl.write(data, [key]) 将 `data` 写入到 `output` 流。`key` 是一个代表键序列的对象;当终端是一个 TTY 时可用。 如果暂停,也会重置 `input` 流。 实例: ~~~ rl.write('Delete me!'); // 模仿 ctrl+u快捷键,删除之前所写行 rl.write(null, {ctrl: true, name: 'u'}); ~~~ ### Events ### Event: 'line' `function (line) {}` 在 `input` 流接受了一个 `\n` 时触发,通常在用户敲击回车或者返回时接收。 这是一个监听用户输入的利器。 监听 `line` 事件的示例: ~~~ rl.on('line', function (cmd) { console.log('You just typed: '+cmd); }); ~~~ ### 事件: 'pause' `function () {}` 不论何时,只要输入流被暂停就会触发。 同样当输入流未被暂停,但收到 `SIGCONT` 也会触发。 (详见 `SIGTSTP` 和 `SIGCONT` 事件) 监听 `pause` 事件的示例: ~~~ rl.on('pause', function() { console.log('Readline 输入暂停.'); }); ~~~ ### 事件: 'resume' `function () {}` 不论何时,只要输入流重新启用就会触发。 监听 `resume` 事件的示例: ~~~ rl.on('resume', function() { console.log('Readline 恢复.'); }); ~~~ ### 事件: 'close' `function () {}` 当 `close()` 被调用时触发。 当 `input`流接收到"结束"事件时也会被触发. 一旦触发,应当认为`Interface`实例 "结束" . 例如, 当`input`流接收到`^D`时, 分别被认为`EOT`. 当 `input` 流接收到一个 `^C` 时,即使没有 `SIGINT` 监听器,也会触发这个事件,分别被称为 `SIGINT` 。 ### Event: 'SIGINT' `function () {}` 只要 `input`流 接收到`^C`就会被触发, 分别被认为`SIGINT`.当`input`流接收到`SIGINT`时, 如果没有 `SIGINT` 事件监听器,`pause` 将会被触发. 监听 `SIGINT` 信号的示例: ~~~ rl.on('SIGINT', function() { rl.question('Are you sure you want to exit?', function(answer) { if (answer.match(/^y(es)?$/i)) rl.pause(); }); }); ~~~ ### Event: 'SIGTSTP' `function () {}` **该功能不支持 windows 操作系统** 只要`input`流接收到`^Z`时就被触发, 分别被认为`SIGTSTP`. 当`input`流接收到 `SIGTSTP`时,如果没有`SIGTSTP` 事件监听器 ,程序会被发送到后台 . 当程序使用参数 `fg` 重启,`pause` 和 `SIGCONT` 事件将会被触发。 你可以使用两者中任一事件来恢复流。 在程序被发送到后台之前,如果流暂停,`pause` 和 `SIGCONT` 事件将不会被触发。 监听 `SIGTSTP` 的示例: ~~~ rl.on('SIGTSTP', function() { // 这将重载 SIGTSTP并防止程序转到 // 后台. console.log('Caught SIGTSTP.'); }); ~~~ ### Event: 'SIGCONT' `function () {}` **该功能不支持 windows 操作系统** 一旦 `input`流中含有 `^Z`并被发送到后台就会触发,分别被认为 `SIGTSTP`, 然后继续执行`fg(1)`. 这一事件只有在流被发送后台之前没有暂停才会触发. 监听 `SIGCONT` 的示例: ~~~ rl.on('SIGCONT', function() { // `prompt` 将会自动恢复流 rl.prompt(); }); ~~~ ### 示例: Tiny CLI 这里有一个使用所有方法精心设计的小命令行程序: ~~~ rl.on('line', function(line) { switch(line.trim()) { case 'hello': console.log('world!'); break; default: console.log('Say what? I might have heard `' + line.trim() + '`'); break; } rl.prompt(); }).on('close', function() { console.log('Have a great day!'); process.exit(0); }); ~~~