readline.clearLine(stream, dir[, callback])
readline.clearScreenDown(stream[, callback])
readline.createInterface(options)
completer
函数的使用
readline.cursorTo(stream, x[, y][, callback])
readline.moveCursor(stream, dx, dy[, callback])
readline.emitKeypressEvents(stream[, interface])
示例:微型 CLI
示例:逐行读取文件流
TTY 键绑定
readline.clearLine(stream, dir[, callback])
readline.clearScreenDown(stream[, callback])
readline.createInterface(options)
completer
函数的使用
readline.cursorTo(stream, x[, y][, callback])
readline.moveCursor(stream, dx, dy[, callback])
readline.emitKeypressEvents(stream[, interface])
示例:微型 CLI
示例:逐行读取文件流
TTY 键绑定
源代码:
lib/readline.js
node:readline
模块提供了一个接口,用于一次一行地从
可读
流(例如
process.stdin
)中读取数据。
要使用基于 promise 的 API:
import * as readline from 'node:readline/promises' ;const readline = require ('node:readline/promises' );拷贝
要使用回调和同步的 API:
import * as readline from 'node:readline' ;const readline = require ('node:readline' );拷贝
下面的简单示例阐明了
node:readline
模块的基本用法。
import * as readline from 'node:readline/promises' ;
import { stdin as input, stdout as output } from 'node:process' ;
const rl = readline.createInterface ({ input, output });
const answer = await rl.question ('What do you think of Node.js? ' );
console .log (`Thank you for your valuable feedback: ${answer} ` );
rl.close ();const readline = require ('node:readline' );
const { stdin : input, stdout : output } = require ('node:process' );
const rl = readline.createInterface ({ input, output });
rl.question ('What do you think of Node.js? ' , (answer ) => {
console .log (`Thank you for your valuable feedback: ${answer} ` );
rl.close ();
});拷贝
一旦调用此代码,则 Node.js 应用将不会终止,直到
readline.Interface
关闭,因为接口在
input
流上等待接收数据。
类:
InterfaceConstructor
#
新增于: v0.1.104
继承:
<EventEmitter>
InterfaceConstructor
类的实例是使用
readlinePromises.createInterface()
或
readline.createInterface()
方法构造的。
每个实例都与单个
input
可读
流和单个
output
可写
流相关联。
output
流用于打印到达并从
input
流中读取的用户输入的提示。
事件:
'close'
#
新增于: v0.1.98
发生以下情况之一时会触发
'close'
事件:
rl.close()
方法被调用,
InterfaceConstructor
实例放弃了对
input
和
output
流的控制;
input
流接收到它的
'end'
事件;
input
流接收
控制键
+
D
触发传输结束信号 (EOT);
input
流接收
控制键
+
C
向
SIGINT
触发信号,并且没有在
InterfaceConstructor
实例上注册
'SIGINT'
事件监听器。
调用监听器函数时不传入任何参数。
一旦触发
'close'
事件,则
InterfaceConstructor
实例就完成了。
新增于: v0.1.98
每当
input
流接收到行尾输入(
\n
、
\r
或
\r\n
)时,则会触发
'line'
事件。 这通常发生在用户按下
进入
或者
返回
.
如果从流中读取了新数据并且该流在没有最终行尾标记的情况下结束,也会触发
'line'
事件。
使用包含单行接收输入的字符串调用监听器函数。
rl.on ('line' , (input ) => {
console .log (`Received: ${input} ` );
}); 拷贝
新增于: v15.8.0, v14.18.0
每当历史数组发生更改时,则会触发
'history'
事件。
使用包含历史数组的数组调用监听器函数。
它将反映由于
historySize
和
removeHistoryDuplicates
引起的所有更改、添加的行和删除的行。
主要目的是允许监听器保留历史记录。
监听器也可以更改历史对象。 这可能有助于防止将某些行添加到历史记录中,例如密码。
rl.on ('history' , (history ) => {
console .log (`Received: ${history} ` );
}); 拷贝
新增于: v0.7.5
发生以下情况之一时会触发
'pause'
事件:
input
流已暂停。
input
流没有暂停并接收
'SIGCONT'
事件。 (参见事件
'SIGTSTP'
和
'SIGCONT'
。)
调用监听器函数时不传入任何参数。
rl.on ('pause' , () => {
console .log ('Readline paused.' );
}); 拷贝
事件:
'resume'
#
新增于: v0.7.5
每当
input
流恢复时,则会触发
'resume'
事件。
调用监听器函数时不传入任何参数。
rl.on ('resume' , () => {
console .log ('Readline resumed.' );
}); 拷贝
新增于: v0.7.5
'SIGCONT'
事件在 Node.js 进程先前使用移动到后台时触发
控制键
+
Z
然后使用
fg(1p)
将(即
SIGTSTP
)带回前台。
如果
input
流在
SIGTSTP
请求之前暂停,则不会触发此事件。
调用监听器函数时不传入任何参数。
rl.on ('SIGCONT' , () => {
rl.prompt ();
}); 拷贝
Windows 不支持
'SIGCONT'
事件。
事件:
'SIGINT'
#
新增于: v0.3.0
每当
input
流接收到一个
Ctrl+C
输入,通常称为
SIGINT
。 如果在
input
流接收到
SIGINT
时没有注册
'SIGINT'
事件监听器,则将触发
'pause'
事件。
调用监听器函数时不传入任何参数。
rl.on ('SIGINT' , () => {
rl.question ('Are you sure you want to exit? ' , (answer ) => {
if (answer.match (/^y(es)?$/i )) rl.pause ();
}); 拷贝
新增于: v0.7.5
'SIGTSTP'
事件在
input
流接收到
控制键
+
Z
输入,通常称为
SIGTSTP
。 如果
input
流接收到
SIGTSTP
时没有注册
'SIGTSTP'
事件监听器,则 Node.js 进程将被发送到后台。
当使用
fg(1p)
恢复程序时,则将触发
'pause'
和
'SIGCONT'
事件。 这些可用于恢复
input
流。
如果
input
在进程发送到后台之前暂停,则不会触发
'pause'
和
'SIGCONT'
事件。
调用监听器函数时不传入任何参数。
rl.on ('SIGTSTP' , () => {
console .log ('Caught SIGTSTP.' );
}); 拷贝
Windows 不支持
'SIGTSTP'
事件。
rl.close()
#
新增于: v0.1.98
rl.close()
方法关闭
InterfaceConstructor
实例并放弃对
input
和
output
流的控制。 当调用时,将触发
'close'
事件。
调用
rl.close()
不会立即阻止其他由
InterfaceConstructor
实例触发的事件(包括
'line'
)。
新增于: v0.3.4
rl.pause()
方法暂停
input
流,允许它稍后在必要时恢复。
调用
rl.pause()
不会立即暂停其他由
InterfaceConstructor
实例触发的事件(包括
'line'
)。
新增于: v0.1.98
preserveCursor
<boolean>
如果为
true
,则防止光标位置重置为
0
。
rl.prompt()
方法将配置为
prompt
的
InterfaceConstructor
实例写入
output
中的新行,以便为用户提供用于提供输入的新位置。
当调用时,如果
rl.prompt()
流已暂停,则
rl.prompt()
将恢复
input
流。
如果
InterfaceConstructor
是在
output
设置为
null
或
undefined
的情况下创建的,则不会写入提示。
rl.resume()
#
新增于: v0.3.4
如果
input
流已暂停,则
rl.resume()
方法会恢复该流。
新增于: v0.1.98
prompt
<string>
rl.setPrompt()
方法设置了在调用
rl.prompt()
时将写入
output
的提示。
rl.getPrompt()
#
新增于: v15.3.0, v14.17.0
返回:
<string>
当前的提示字符串
rl.getPrompt()
方法返回
rl.prompt()
使用的当前提示。
rl.write(data[, key])
#
新增于: v0.1.98
data
<string>
key
<Object>
ctrl
<boolean>
true
表示
控制键
钥匙。
meta
<boolean>
true
表示
元
钥匙。
shift
<boolean>
true
表示
转移
钥匙。
name
<string>
键的名称。
rl.write()
方法会将
data
或由
key
标识的键序列写入
output
。 仅当
output
是
TTY
文本终端时才支持
key
参数。 有关组合键列表,请参阅
TTY 键绑定
。
如果指定了
key
,则忽略
data
。
当调用时,如果
rl.write()
流已暂停,则
rl.write()
将恢复
input
流。
如果
InterfaceConstructor
是在
output
设置为
null
或
undefined
的情况下创建的,则不会写入
data
和
key
。
rl.write ('Delete this!' );
rl.write (null , { ctrl : true , name : 'u' }); 拷贝
rl.write()
方法会将数据写入
readline
Interface
的
input
,就好像它是由用户提供的一样。
rl[Symbol.asyncIterator]()
#
版本变更
v11.14.0, v10.17.0
Symbol.asyncIterator 支持不再是实验的。
v11.4.0, v10.16.0
新增于: v11.4.0, v10.16.0
返回:
<AsyncIterator>
创建
AsyncIterator
对象,该对象遍历输入流中的每一行作为字符串。 此方法允许通过
for await...of
循环异步迭代
InterfaceConstructor
对象。
输入流中的错误不会被转发。
如果循环以
break
、
throw
或
return
终止,则将调用
rl.close()
。 换句话说,迭代
InterfaceConstructor
将始终完全消费输入流。
性能无法与传统的
'line'
事件 API 相提并论。 对于性能敏感的应用,请改用
'line'
。
async function processLineByLine () {
const rl = readline.createInterface ({
for await (const line of rl) {
} 拷贝
readline.createInterface()
将在调用后开始使用输入流。 在接口创建和异步迭代之间进行异步操作可能会导致丢失行。
rl.line
#
版本变更
v15.8.0, v14.18.0
值将始终是字符串,永远不会未定义。
v0.1.98
新增于: v0.1.98
节点正在处理的当前输入数据。
这可用于从 TTY 流中收集输入以检索迄今为止(在
line
事件触发之前)已处理的当前值。 一旦触发
line
事件,则此属性将是空字符串。
请注意,如果
rl.cursor
也不受控制,则在实例运行时修改该值可能会产生意想不到的后果。
如果不使用 TTY 流进行输入,请使用
'line'
事件。
一个可能的用例如下:
const values = ['lorem ipsum' , 'dolor sit amet' ];
const rl = readline.createInterface (process.stdin );
const showResults = debounce (() => {
console .log (
'\n' ,
values.filter ((val ) => val.startsWith (rl.line )).join (' ' ),
}, 300 );
process.stdin .on ('keypress' , (c, k ) => {
showResults ();
}); 拷贝
rl.cursor
#
新增于: v0.1.98
<number>
|
<undefined>
相对于
rl.line
的光标位置。
当从 TTY 流读取输入时,这将跟踪当前光标在输入字符串中的位置。 光标的位置决定了在处理输入时将被修改的输入字符串部分,以及将渲染终端插入符号的列。
rl.getCursorPos()
#
新增于: v13.5.0, v12.16.0
返回:
<Object>
rows
<number>
光标当前所在的提示行
cols
<number>
光标当前所在的屏幕列
返回光标相对于输入提示 + 字符串的实际位置。 长输入(换行)字符串以及多行提示都包含在计算中。
Promises API
#
新增于: v17.0.0
类:
readlinePromises.Interface
#
新增于: v17.0.0
继承:
<readline.InterfaceConstructor>
readlinePromises.Interface
类的实例是使用
readlinePromises.createInterface()
方法构造的。 每个实例都与单个
input
可读
流和单个
output
可写
流相关联。
output
流用于打印到达并从
input
流中读取的用户输入的提示。
rl.question(query[, options])
#
新增于: v17.0.0
query
<string>
要写入
output
的语句或查询,位于提示之前。
options
<Object>
signal
<AbortSignal>
可选择允许使用
AbortSignal
取消
question()
。
返回:
<Promise>
使用用户响应
query
的输入履行的 promise。
rl.question()
方法通过将
query
写入
output
来显示
query
,等待在
input
上提供用户输入,然后调用
callback
函数,将提供的输入作为第一个参数传入。
当调用时,如果
rl.question()
流已暂停,则
rl.question()
将恢复
input
流。
如果
readlinePromises.Interface
是在
output
设置为
null
或
undefined
的情况下创建的,则不会写入
query
。
如果问题在
rl.close()
之后被调用,则它返回被拒绝的 promise。
用法示例:
const answer = await rl.question ('What is your favorite food? ' );
console .log (`Oh, so your favorite food is ${answer} ` ); 拷贝
使用
AbortSignal
取消问题。
const signal = AbortSignal .timeout (10_000 );
signal.addEventListener ('abort' , () => {
console .log ('The food question timed out' );
}, { once : true });
const answer = await rl.question ('What is your favorite food? ' , { signal });
console .log (`Oh, so your favorite food is ${answer} ` ); 拷贝
类:
readlinePromises.Readline
#
新增于: v17.0.0
新增于: v17.0.0
stream
<stream.Writable>
TTY
流。
options
<Object>
autoCommit
<boolean>
如果是
true
,则不需要调用
rl.commit()
。
rl.clearLine()
方法在待处理动作的内部列表中添加一个动作,该动作在
dir
标识的指定方向上清除关联
stream
的当前行。
调用
rl.commit()
看看这个方法的效果,除非
autoCommit: true
传给了构造函数。
rl.clearScreenDown()
#
新增于: v17.0.0
返回: 自身
rl.clearScreenDown()
方法向待处理动作的内部列表添加一个动作,该动作从光标向下的当前位置清除关联流。
调用
rl.commit()
看看这个方法的效果,除非
autoCommit: true
传给了构造函数。
新增于: v17.0.0
返回:
<Promise>
rl.commit()
方法将所有待处理的操作发送到关联的
stream
并清除待处理操作的内部列表。
rl.cursorTo(x[, y])
#
新增于: v17.0.0
x
<integer>
y
<integer>
返回: 自身
rl.cursorTo()
方法向待处理动作的内部列表添加一个动作,该动作将光标移动到相关
stream
中指定的位置。
调用
rl.commit()
看看这个方法的效果,除非
autoCommit: true
传给了构造函数。
rl.moveCursor(dx, dy)
#
新增于: v17.0.0
dx
<integer>
dy
<integer>
返回: 自身
rl.moveCursor()
方法向待处理操作的内部列表添加一个操作,该操作将光标相对于关联的
stream
中的当前位置移动。
调用
rl.commit()
看看这个方法的效果,除非
autoCommit: true
传给了构造函数。
rl.rollback()
#
新增于: v17.0.0
返回: 自身
rl.rollback
方法清除内部待处理操作列表,而不将其发送到关联的
stream
。
新增于: v17.0.0
options
<Object>
input
<stream.Readable>
要收听的
可读
流。 此选项是必需的。
output
<stream.Writable>
要写入 readline 数据的
可写
流。
completer
<Function>
可选的用于制表符自动补全的函数。
terminal
<boolean>
如果
input
和
output
流应该被视为终端,并且写入了 ANSI/VT100 转义码,则为
true
。
默认值:
在实例化时检查
output
流上的
isTTY
。
history
<string[]>
历史行的初始列表。 仅当
terminal
由用户或内部的
output
检查设置为
true
时,此选项才有意义,否则历史缓存机制根本不会初始化。
默认值:
[]
。
historySize
<number>
保留的最大历史行数。 要禁用历史记录,则将此值设置为
0
。 仅当
terminal
由用户或内部的
output
检查设置为
true
时,此选项才有意义,否则历史缓存机制根本不会初始化。
默认值:
30
。
removeHistoryDuplicates
<boolean>
如果为
true
,则当添加到历史列表的新输入行与旧输入行重复时,这将从列表中删除旧行。
默认值:
false
。
prompt
<string>
要使用的提示字符串。
默认值:
'> '
。
crlfDelay
<number>
如果
\r
和
\n
之间的延迟超过
crlfDelay
毫秒,则
\r
和
\n
都将被视为单独的行尾输入。
crlfDelay
将被强制为不小于
100
的数字。 它可以设置为
Infinity
,在这种情况下,
\r
后跟
\n
将始终被视为单个换行符(这对于带有
\r\n
行分隔符的
读取文件
可能是合理的)。
默认值:
100
。
escapeCodeTimeout
<number>
readlinePromises
将等待字符的时长(当以毫秒为单位读取不明确的键序列时,既可以使用目前读取的输入形成完整的键序列,又可以采用额外的输入来完成更长的键序列)。
默认值:
500
。
tabSize
<integer>
一个制表符等于的空格数(最小为 1)。
默认值:
8
。
返回:
<readlinePromises.Interface>
readlinePromises.createInterface()
方法创建新的
readlinePromises.Interface
实例。
const readlinePromises = require ('node:readline/promises' );
const rl = readlinePromises.createInterface ({
input : process.stdin ,
output : process.stdout ,
}); 拷贝
一旦创建了
readlinePromises.Interface
实例,则最常见的场景就是监听
'line'
事件:
rl.on ('line' , (line ) => {
console .log (`Received: ${line} ` );
}); 拷贝
如果此实例的
terminal
是
true
,则如果它定义了
output.columns
属性,并且如果或当列发生变化时(
process.stdout
会当其是终端时自动执行此操作)在
output
上触发
'resize'
事件,则
output
流将获得最佳的兼容性。
completer
函数的使用
#
completer
函数将用户输入的当前行作为参数,并返回包含 2 个条目的
Array
:
使用匹配条目的
Array
补全。
用于匹配的子字符串。
例如:
[[substr1, substr2, ...], originalsubstring]
。
function completer (line ) {
const completions = '.help .error .exit .quit .q' .split (' ' );
const hits = completions.filter ((c ) => c.startsWith (line));
return [hits.length ? hits : completions, line];
} 拷贝
completer
函数也可以返回
<Promise>
,或者是异步的:
async function completer (linePartial ) {
await someAsyncWork ();
return [['123' ], linePartial];
} 拷贝
回调接口
#
新增于: v0.1.104
版本变更
v17.0.0
readline.Interface
类现在继承自
Interface
。
v0.1.104
新增于: v0.1.104
继承:
<readline.InterfaceConstructor>
readline.Interface
类的实例是使用
readline.createInterface()
方法构造的。 每个实例都与单个
input
可读
流和单个
output
可写
流相关联。
output
流用于打印到达并从
input
流中读取的用户输入的提示。
rl.question(query[, options], callback)
#
新增于: v0.3.3
query
<string>
要写入
output
的语句或查询,位于提示之前。
options
<Object>
signal
<AbortSignal>
可选择允许使用
AbortController
取消
question()
。
callback
<Function>
使用用户输入调用的回调函数以响应
query
。
rl.question()
方法通过将
query
写入
output
来显示
query
,等待在
input
上提供用户输入,然后调用
callback
函数,将提供的输入作为第一个参数传入。
当调用时,如果
rl.question()
流已暂停,则
rl.question()
将恢复
input
流。
如果
readline.Interface
是在
output
设置为
null
或
undefined
的情况下创建的,则不会写入
query
。
传给
rl.question()
的
callback
函数不遵循接受
Error
对象或
null
作为第一个参数的典型模式。
以提供的答案作为唯一参数调用
callback
。
在
rl.close()
之后调用
rl.question()
会报错。
用法示例:
rl.question ('What is your favorite food? ' , (answer ) => {
console .log (`Oh, so your favorite food is ${answer} ` );
}); 拷贝
使用
AbortController
取消问题。
const ac = new AbortController ();
const signal = ac.signal ;
rl.question ('What is your favorite food? ' , { signal }, (answer ) => {
console .log (`Oh, so your favorite food is ${answer} ` );
signal.addEventListener ('abort' , () => {
console .log ('The food question timed out' );
}, { once : true });
setTimeout (() => ac.abort (), 10000 ); 拷贝
readline.clearLine(stream, dir[, callback])
#
版本变更
v18.0.0
将无效回调传给
callback
参数现在会抛出
ERR_INVALID_ARG_TYPE
而不是
ERR_INVALID_CALLBACK
。
v12.7.0
流的 write() 回调和返回值是公开的。
v0.7.7
新增于: v0.7.7
callback
<Function>
操作完成后调用。
返回:
<boolean>
false
如果
stream
希望调用代码在继续写入额外数据之前等待
'drain'
事件触发;
否则
true
。
readline.clearLine()
方法在
dir
标识的指定方向上清除给定
TTY
流的当前行。
readline.clearScreenDown(stream[, callback])
#
版本变更
v18.0.0
将无效回调传给
callback
参数现在会抛出
ERR_INVALID_ARG_TYPE
而不是
ERR_INVALID_CALLBACK
。
v12.7.0
流的 write() 回调和返回值是公开的。
v0.7.7
新增于: v0.7.7
stream
<stream.Writable>
callback
<Function>
操作完成后调用。
返回:
<boolean>
false
如果
stream
希望调用代码在继续写入额外数据之前等待
'drain'
事件触发;
否则
true
。
readline.clearScreenDown()
方法从光标的当前位置向下清除给定的
TTY
流。
readline.createInterface(options)
#
版本变更
v15.14.0, v14.18.0
现在支持
signal
选项。
v15.8.0, v14.18.0
现在支持
history
选项。
v13.9.0
现在支持
tabSize
选项。
v8.3.0, v6.11.4
删除
crlfDelay
选项的最大限制。
v6.6.0
现在支持
crlfDelay
选项。
v6.3.0
现在支持
prompt
选项。
v6.0.0
选项
historySize
现在可以是
0
。
v0.1.98
新增于: v0.1.98
input
<stream.Readable>
要收听的
可读
流。 此选项是必需的。
output
<stream.Writable>
要写入 readline 数据的
可写
流。
completer
<Function>
可选的用于制表符自动补全的函数。
terminal
<boolean>
如果
input
和
output
流应该被视为终端,并且写入了 ANSI/VT100 转义码,则为
true
。
默认值:
在实例化时检查
output
流上的
isTTY
。
history
<string[]>
历史行的初始列表。 仅当
terminal
由用户或内部的
output
检查设置为
true
时,此选项才有意义,否则历史缓存机制根本不会初始化。
默认值:
[]
。
historySize
<number>
保留的最大历史行数。 要禁用历史记录,则将此值设置为
0
。 仅当
terminal
由用户或内部的
output
检查设置为
true
时,此选项才有意义,否则历史缓存机制根本不会初始化。
默认值:
30
。
removeHistoryDuplicates
<boolean>
如果为
true
,则当添加到历史列表的新输入行与旧输入行重复时,这将从列表中删除旧行。
默认值:
false
。
prompt
<string>
要使用的提示字符串。
默认值:
'> '
。
crlfDelay
<number>
如果
\r
和
\n
之间的延迟超过
crlfDelay
毫秒,则
\r
和
\n
都将被视为单独的行尾输入。
crlfDelay
将被强制为不小于
100
的数字。 它可以设置为
Infinity
,在这种情况下,
\r
后跟
\n
将始终被视为单个换行符(这对于带有
\r\n
行分隔符的
读取文件
可能是合理的)。
默认值:
100
。
escapeCodeTimeout
<number>
readline
将等待字符的时长(当以毫秒为单位读取不明确的键序列时,既可以使用目前读取的输入形成完整的键序列,又可以采用额外的输入来完成更长的键序列)。
默认值:
500
。
tabSize
<integer>
一个制表符等于的空格数(最小为 1)。
默认值:
8
。
signal
<AbortSignal>
允许使用中止信号关闭接口。
中止信号将在内部调用接口上的
close
。
返回:
<readline.Interface>
readline.createInterface()
方法创建新的
readline.Interface
实例。
const readline = require ('node:readline' );
const rl = readline.createInterface ({
input : process.stdin ,
output : process.stdout ,
}); 拷贝
一旦创建了
readline.Interface
实例,则最常见的场景就是监听
'line'
事件:
rl.on ('line' , (line ) => {
console .log (`Received: ${line} ` );
}); 拷贝
如果此实例的
terminal
是
true
,则如果它定义了
output.columns
属性,并且如果或当列发生变化时(
process.stdout
会当其是终端时自动执行此操作)在
output
上触发
'resize'
事件,则
output
流将获得最佳的兼容性。
当使用
stdin
作为输入创建
readline.Interface
时,程序将不会终止,直到它收到
EOF 字符
。 要在不等待用户输入的情况下退出,则调用
process.stdin.unref()
。
completer
函数的使用
#
completer
函数将用户输入的当前行作为参数,并返回包含 2 个条目的
Array
:
使用匹配条目的
Array
补全。
用于匹配的子字符串。
例如:
[[substr1, substr2, ...], originalsubstring]
。
function completer (line ) {
const completions = '.help .error .exit .quit .q' .split (' ' );
const hits = completions.filter ((c ) => c.startsWith (line));
return [hits.length ? hits : completions, line];
} 拷贝
如果
completer
函数接受两个参数,则可以异步地调用它:
function completer (linePartial, callback ) {
callback (null , [['123' ], linePartial]);
} 拷贝
版本变更
v18.0.0
将无效回调传给
callback
参数现在会抛出
ERR_INVALID_ARG_TYPE
而不是
ERR_INVALID_CALLBACK
。
v12.7.0
流的 write() 回调和返回值是公开的。
v0.7.7
新增于: v0.7.7
y
<number>
callback
<Function>
操作完成后调用。
返回:
<boolean>
false
如果
stream
希望调用代码在继续写入额外数据之前等待
'drain'
事件触发;
否则
true
。
readline.cursorTo()
方法将光标移动到给定的
TTY
stream
中的指定位置。
readline.moveCursor(stream, dx, dy[, callback])
#
版本变更
v18.0.0
将无效回调传给
callback
参数现在会抛出
ERR_INVALID_ARG_TYPE
而不是
ERR_INVALID_CALLBACK
。
v12.7.0
流的 write() 回调和返回值是公开的。
v0.7.7
新增于: v0.7.7
dy
<number>
callback
<Function>
操作完成后调用。
返回:
<boolean>
false
如果
stream
希望调用代码在继续写入额外数据之前等待
'drain'
事件触发;
否则
true
。
readline.moveCursor()
方法将光标相对于其在给定
TTY
stream
中的当前位置移动。
readline.emitKeypressEvents(stream[, interface])
#
新增于: v0.7.7
stream
<stream.Readable>
interface
<readline.InterfaceConstructor>
readline.emitKeypressEvents()
方法使给定的
可读
流开始触发与接收到的输入相对应的
'keypress'
事件。
可选地,
interface
指定
readline.Interface
实例,当检测到复制粘贴输入时禁用自动补齐。
如果
stream
是
TTY
,则它必须处于原始模式。
如果
input
是终端,则它会被其
input
上的任何逐行读取实例自动调用。 关闭
readline
实例不会阻止
input
触发
'keypress'
事件。
readline.emitKeypressEvents (process.stdin );
if (process.stdin .isTTY )
process.stdin .setRawMode (true ); 拷贝
readline
的一个常见用例是每次一行地消费输入文件。 最简单的方式是利用
fs.ReadStream
API 和
for await...of
循环:
const fs = require ('node:fs' );
const readline = require ('node:readline' );
async function processLineByLine () {
const fileStream = fs.createReadStream ('input.txt' );
const rl = readline.createInterface ({
input : fileStream,
crlfDelay : Infinity ,
for await (const line of rl) {
console .log (`Line from file: ${line} ` );
processLineByLine (); 拷贝
或者,可以使用
'line'
事件:
const fs = require ('node:fs' );
const readline = require ('node:readline' );
const rl = readline.createInterface ({
input : fs.createReadStream ('sample.txt' ),
crlfDelay : Infinity ,
rl.on ('line' , (line ) => {
console .log (`Line from file: ${line} ` );
}); 拷贝
目前,
for await...of
循环可能会慢一点。 如果
async
/
await
流量和速度都必不可少,则可以应用混合方法:
const { once } = require ('node:events' );
const { createReadStream } = require ('node:fs' );
const { createInterface } = require ('node:readline' );
(async function processLineByLine () {
try {
const rl = createInterface ({
input : createReadStream ('big-file.txt' ),
crlfDelay : Infinity ,
rl.on ('line' , (line ) => {
await once (rl, 'close' );
console .log ('File processed.' );
} catch (err) {
console .error (err);
})(); 拷贝