本节介绍node.js readline(逐行读取)模块,它用于提供一个接口。
稳定性: 2 - 不稳定
通过 require('readline')
,你可以使用这个模块。逐行读取(readline)可以逐行读取流(比如process.stdin
)。
访问该模块的方法如下:
const readline = require('readline');
一旦你开启了这个模块,node程序将不会终止,直到你关闭接口。以下的代码展示了如何优雅的退出程序:
var readline = require('readline');
var rl = readline.createinterface({
input: process.stdin,
output: process.stdout
});
rl.question("what do you think of node.js? ", function(answer) {
// todo: log the answer in a database
console.log("thank you for your valuable feedback:", answer);
rl.close();
});
创建一个逐行读取(readline)interface
实例。参数"options"对象有以下值:
input
- 监听的可读流 (必填)。
output
- 逐行读取(readline)数据要写入的可写流(可选)。
completer
- 用于tab自动补全的可选函数。参见下面的例子。
terminal
- 如果希望和tty一样,对待input
和output
流,设置为true。并且由ansi/vt100转码。默认情况下,检查istty
是否在output
流上实例化。completer
给出当前行的入口,应该返回包含2条记录的数组。
一个匹配当前输入补全的字符串数组
最终像这样:[[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
可以异步运行,此时接收到2个参数:
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.columns
属性,那么output
流将会最佳兼容性,并且,当columns变化时(当它是tty时,process.stdout
会自动这么做),会在output
流上触发"resize"
事件。
代表一个包含输入/输出流的逐行读取(readline)接口的类。
设置提示符,比如当你再命令行里运行node
时,可以看到node的提示符>
。
为用户输入准备好逐行读取(readline),将当前setprompt
选项方法哦新的行中,让用户有新的地方输入。设置preservecursor
为true
,防止当前的游标重置为0
。
如果暂停,使用createinterface
也可以重置input
输入流。
调用createinterface
时,如果output
设置为null
或undefined
,不会重新写提示符。
预先提示query
,用户应答后触发callback
。给用户显示query后,用户应答被输入后,调用callback
。
如果暂停,使用createinterface
也可以重置input
输入流。
调用createinterface
时,如果output
设置为null
或undefined
,不会重新写提示符。
例子:
interface.question('what is your favorite food?', function(answer) {
console.log('oh, so your favorite food is ' + answer);
});
暂停逐行读取(readline)的input
输入流, 如果需要可以重新启动。
注意,这不会立即暂停流。调用pause
后还会有很多事件触发,包含line
。
恢复 逐行读取(readline)input
输入流.
关闭interface
实例, 放弃控制输入输出流。会触发"close"事件。
调用createinterface
后,将数据data
写到output
输出流,除非output
为null
,或未定义undefined
。key
是一个代表键序列的对象;当终端是一个 tty 时可用。
暂停input
输入流后,这个方法可以恢复。
例子:
rl.write('delete me!');
// simulate ctrl+u to delete the line written previously
rl.write(null, {ctrl: true, name: 'u'});
function (line) {}
input
输入流收到\n
后触发,通常因为用户敲回车或返回键。这是监听用户输入的好办法。
监听line
的例子:
rl.on('line', function (cmd) {
console.log('you just typed: '+cmd);
});
function () {}
暂停input
输入流后,会触发这个方法。
当输入流未被暂停,但收到sigcont
也会触发。 (详见sigtstp
和sigcont
事件)
监听pause
的例子:
rl.on('pause', function() {
console.log('readline paused.');
});
function () {}
恢复input
输入流后,会触发这个方法。
监听resume
的例子:
rl.on('resume', function() {
console.log('readline resumed.');
});
function () {}
调用close()
方法时会触发。
当input
输入流收到"end"事件时会触发。一旦触发,可以认为interface
实例结束。例如当input
输入流收到^d
,被当做eot
。
如果没有sigint
事件监听器,当input
输入流接收到^c
(被当做sigint
),也会触发这个事件。
function () {}
当input
输入流收到^c
时会触发, 被当做sigint
。如果没有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();
});
});
function () {}
windows 里不可用
当input
输入流收到^z
时会触发,被当做sigtstp
。如果没有sigint
事件监听器,当input
输入流接收到sigtstp
,程序将会切换到后台。
当程序通过fg
恢复,将会触发pause
和sigcont
事件。你可以使用两者中任一事件来恢复流。
程切换到后台前,如果暂停了流,pause
和 sigcont
事件不会被触发。
监听sigtstp
的例子:
rl.on('sigtstp', function() {
// this will override sigtstp and prevent the program from going to the
// background.
console.log('caught sigtstp.');
});
function () {}
windows里不可用
一旦input流中含有^z并被切换到后台就会触发。被当做sigtstp
,然后继续执行fg(1)
。程切换到后台前,如果流没被暂停,这个事件可以被触发。
监听sigcont
的例子:
rl.on('sigcont', function() {
// `prompt` will automatically resume the stream
rl.prompt();
});
以下的例子,展示了如何所有这些方法的命令行接口:
var readline = require('readline'),
rl = readline.createinterface(process.stdin, process.stdout);
rl.setprompt('ohai> ');
rl.prompt();
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);
});
在tty流里,移动光标到指定位置。
在tty流里,移动光标到当前位置的相对位置。
清空tty流里指定方向的行。dir
是以下值:
-1
- 从光标到左边1
- 从光标到右边0
- 整行清空屏幕上从当前光标位置起的内容。