- assert 断言
- async_hooks 异步钩子
- async_hooks/context 异步上下文
- buffer 缓冲区
- C++插件
- C/C++插件(使用 Node-API)
- C++嵌入器
- child_process 子进程
- cluster 集群
- CLI 命令行
- console 控制台
- Corepack 核心包
- crypto 加密
- crypto/webcrypto 网络加密
- debugger 调试器
- deprecation 弃用
- dgram 数据报
- diagnostics_channel 诊断通道
- dns 域名服务器
- domain 域
- Error 错误
- events 事件触发器
- fs 文件系统
- global 全局变量
- http 超文本传输协议
- http2 超文本传输协议 2.0
- https 安全超文本传输协议
- inspector 检查器
- Intl 国际化
- module 模块
- module/cjs CommonJS 模块
- module/esm ECMAScript 模块
- module/package 包模块
- module/typescript TS 模块
- net 网络
- os 操作系统
- path 路径
- perf_hooks 性能钩子
- permission 权限
- process 进程
- punycode 域名代码
- querystring 查询字符串
- readline 逐行读取
- repl 交互式解释器
- report 诊断报告
- sea 单个可执行应用程序
Node.js v22.12.0 文档
- Node.js v22.12.0
- 目录
-
导航
- assert 断言
- async_hooks 异步钩子
- async_hooks/context 异步上下文
- buffer 缓冲区
- C++插件
- C/C++插件(使用 Node-API)
- C++嵌入器
- child_process 子进程
- cluster 集群
- CLI 命令行
- console 控制台
- Corepack 核心包
- crypto 加密
- crypto/webcrypto 网络加密
- debugger 调试器
- deprecation 弃用
- dgram 数据报
- diagnostics_channel 诊断通道
- dns 域名服务器
- domain 域
- Error 错误
- events 事件触发器
- fs 文件系统
- global 全局变量
- http 超文本传输协议
- http2 超文本传输协议 2.0
- https 安全超文本传输协议
- inspector 检查器
- Intl 国际化
- module 模块
- module/cjs CommonJS 模块
- module/esm ECMAScript 模块
- module/package 包模块
- module/typescript TS 模块
- net 网络
- os 操作系统
- path 路径
- perf_hooks 性能钩子
- permission 权限
- process 进程
- punycode 域名代码
- querystring 查询字符串
- readline 逐行读取
- repl 交互式解释器
- report 诊断报告
- sea 单个可执行应用程序
- 其他版本
逐行读取#
¥Readline
¥Stability: 2 - Stable
源代码: lib/readline.js
node:readline
模块提供了一个接口,用于一次一行地从 可读 流(例如 process.stdin
)中读取数据。
¥The node:readline
module provides an interface for reading data from a
Readable stream (such as process.stdin
) one line at a time.
要使用基于 promise 的 API:
¥To use the promise-based APIs:
import * as readline from 'node:readline/promises';
const readline = require('node:readline/promises');
要使用回调和同步的 API:
¥To use the callback and sync APIs:
import * as readline from 'node:readline';
const readline = require('node:readline');
下面的简单示例阐明了 node:readline
模块的基本用法。
¥The following simple example illustrates the basic use of the node:readline
module.
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) => {
// TODO: Log the answer in a database
console.log(`Thank you for your valuable feedback: ${answer}`);
rl.close();
});
一旦调用此代码,则 Node.js 应用将不会终止,直到 readline.Interface
关闭,因为接口在 input
流上等待接收数据。
¥Once this code is invoked, the Node.js application will not terminate until the
readline.Interface
is closed because the interface waits for data to be
received on the input
stream.
类:InterfaceConstructor
#
¥Class: InterfaceConstructor
-
¥Extends: <EventEmitter>
InterfaceConstructor
类的实例是使用 readlinePromises.createInterface()
或 readline.createInterface()
方法构造的。每个实例都与单个 input
可读 流和单个 output
可写 流相关联。output
流用于打印到达并从 input
流中读取的用户输入的提示。
¥Instances of the InterfaceConstructor
class are constructed using the
readlinePromises.createInterface()
or readline.createInterface()
method.
Every instance is associated with a single input
Readable stream and a
single output
Writable stream.
The output
stream is used to print prompts for user input that arrives on,
and is read from, the input
stream.
事件:'close'
#
¥Event: 'close'
发生以下情况之一时会触发 'close'
事件:
¥The 'close'
event is emitted when one of the following occur:
-
rl.close()
方法被调用,InterfaceConstructor
实例放弃了对input
和output
流的控制;¥The
rl.close()
method is called and theInterfaceConstructor
instance has relinquished control over theinput
andoutput
streams; -
input
流接收到它的'end'
事件;¥The
input
stream receives its'end'
event; -
input
流接收 Ctrl+D 以表示传输结束(EOT);¥The
input
stream receives Ctrl+D to signal end-of-transmission (EOT); -
input
流接收 Ctrl+C 来向SIGINT
触发信号,并且InterfaceConstructor
实例上没有注册'SIGINT'
事件监听器。¥The
input
stream receives Ctrl+C to signalSIGINT
and there is no'SIGINT'
event listener registered on theInterfaceConstructor
instance.
调用监听器函数时不传入任何参数。
¥The listener function is called without passing any arguments.
一旦触发 'close'
事件,则 InterfaceConstructor
实例就完成了。
¥The InterfaceConstructor
instance is finished once the 'close'
event is
emitted.
事件:'line'
#
¥Event: 'line'
每当 input
流接收到行尾输入(\n
、\r
或 \r\n
)时,则会触发 'line'
事件。这通常在用户按 Enter 或 Return 时发生。
¥The 'line'
event is emitted whenever the input
stream receives an
end-of-line input (\n
, \r
, or \r\n
). This usually occurs when the user
presses Enter or Return.
如果从流中读取了新数据并且该流在没有最终行尾标记的情况下结束,也会触发 'line'
事件。
¥The 'line'
event is also emitted if new data has been read from a stream and
that stream ends without a final end-of-line marker.
使用包含单行接收输入的字符串调用监听器函数。
¥The listener function is called with a string containing the single line of received input.
rl.on('line', (input) => {
console.log(`Received: ${input}`);
});
事件:'history'
#
¥Event: 'history'
每当历史数组发生更改时,则会触发 'history'
事件。
¥The 'history'
event is emitted whenever the history array has changed.
使用包含历史数组的数组调用监听器函数。它将反映由于 historySize
和 removeHistoryDuplicates
引起的所有更改、添加的行和删除的行。
¥The listener function is called with an array containing the history array.
It will reflect all changes, added lines and removed lines due to
historySize
and removeHistoryDuplicates
.
主要目的是允许监听器保留历史记录。监听器也可以更改历史对象。这可能有助于防止将某些行添加到历史记录中,例如密码。
¥The primary purpose is to allow a listener to persist the history. It is also possible for the listener to change the history object. This could be useful to prevent certain lines to be added to the history, like a password.
rl.on('history', (history) => {
console.log(`Received: ${history}`);
});
事件:'pause'
#
¥Event: 'pause'
发生以下情况之一时会触发 'pause'
事件:
¥The 'pause'
event is emitted when one of the following occur:
-
input
流已暂停。¥The
input
stream is paused. -
input
流没有暂停并接收'SIGCONT'
事件。(参见事件'SIGTSTP'
和'SIGCONT'
。)¥The
input
stream is not paused and receives the'SIGCONT'
event. (See events'SIGTSTP'
and'SIGCONT'
.)
调用监听器函数时不传入任何参数。
¥The listener function is called without passing any arguments.
rl.on('pause', () => {
console.log('Readline paused.');
});
事件:'resume'
#
¥Event: 'resume'
每当 input
流恢复时,则会触发 'resume'
事件。
¥The 'resume'
event is emitted whenever the input
stream is resumed.
调用监听器函数时不传入任何参数。
¥The listener function is called without passing any arguments.
rl.on('resume', () => {
console.log('Readline resumed.');
});
事件:'SIGCONT'
#
¥Event: 'SIGCONT'
当先前使用 Ctrl+Z(即 SIGTSTP
)移至后台的 Node.js 进程随后使用 fg(1p)
返回前台时,会触发 'SIGCONT'
事件。
¥The 'SIGCONT'
event is emitted when a Node.js process previously moved into
the background using Ctrl+Z (i.e. SIGTSTP
) is then
brought back to the foreground using fg(1p)
.
如果 input
流在 SIGTSTP
请求之前暂停,则不会触发此事件。
¥If the input
stream was paused before the SIGTSTP
request, this event will
not be emitted.
调用监听器函数时不传入任何参数。
¥The listener function is invoked without passing any arguments.
rl.on('SIGCONT', () => {
// `prompt` will automatically resume the stream
rl.prompt();
});
Windows 不支持 'SIGCONT'
事件。
¥The 'SIGCONT'
event is not supported on Windows.
事件:'SIGINT'
#
¥Event: 'SIGINT'
每当 input
流接收到 Ctrl+C 输入(通常称为 SIGINT
)时,就会触发 'SIGINT'
事件。如果在 input
流接收到 SIGINT
时没有注册 'SIGINT'
事件监听器,则将触发 'pause'
事件。
¥The 'SIGINT'
event is emitted whenever the input
stream receives
a Ctrl+C input, known typically as SIGINT
. If there are no
'SIGINT'
event listeners registered when the input
stream receives a
SIGINT
, the 'pause'
event will be emitted.
调用监听器函数时不传入任何参数。
¥The listener function is invoked without passing any arguments.
rl.on('SIGINT', () => {
rl.question('Are you sure you want to exit? ', (answer) => {
if (answer.match(/^y(es)?$/i)) rl.pause();
});
});
事件:'SIGTSTP'
#
¥Event: 'SIGTSTP'
当 input
流接收到 Ctrl+Z 输入(通常称为 SIGTSTP
)时,会触发 'SIGTSTP'
事件。如果 input
流接收到 SIGTSTP
时没有注册 'SIGTSTP'
事件监听器,则 Node.js 进程将被发送到后台。
¥The 'SIGTSTP'
event is emitted when the input
stream receives
a Ctrl+Z input, typically known as SIGTSTP
. If there are
no 'SIGTSTP'
event listeners registered when the input
stream receives a
SIGTSTP
, the Node.js process will be sent to the background.
当使用 fg(1p)
恢复程序时,则将触发 'pause'
和 'SIGCONT'
事件。这些可用于恢复 input
流。
¥When the program is resumed using fg(1p)
, the 'pause'
and 'SIGCONT'
events
will be emitted. These can be used to resume the input
stream.
如果 input
在进程发送到后台之前暂停,则不会触发 'pause'
和 'SIGCONT'
事件。
¥The 'pause'
and 'SIGCONT'
events will not be emitted if the input
was
paused before the process was sent to the background.
调用监听器函数时不传入任何参数。
¥The listener function is invoked without passing any arguments.
rl.on('SIGTSTP', () => {
// This will override SIGTSTP and prevent the program from going to the
// background.
console.log('Caught SIGTSTP.');
});
Windows 不支持 'SIGTSTP'
事件。
¥The 'SIGTSTP'
event is not supported on Windows.
rl.close()
#
rl.close()
方法关闭 InterfaceConstructor
实例并放弃对 input
和 output
流的控制。当调用时,将触发 'close'
事件。
¥The rl.close()
method closes the InterfaceConstructor
instance and
relinquishes control over the input
and output
streams. When called,
the 'close'
event will be emitted.
调用 rl.close()
不会立即阻止其他由 InterfaceConstructor
实例触发的事件(包括 'line'
)。
¥Calling rl.close()
does not immediately stop other events (including 'line'
)
from being emitted by the InterfaceConstructor
instance.
rl.pause()
#
rl.pause()
方法暂停 input
流,允许它稍后在必要时恢复。
¥The rl.pause()
method pauses the input
stream, allowing it to be resumed
later if necessary.
调用 rl.pause()
不会立即暂停其他由 InterfaceConstructor
实例触发的事件(包括 'line'
)。
¥Calling rl.pause()
does not immediately pause other events (including
'line'
) from being emitted by the InterfaceConstructor
instance.
rl.prompt([preserveCursor])
#
-
preserveCursor
<boolean> 如果为true
,则防止光标位置重置为0
。¥
preserveCursor
<boolean> Iftrue
, prevents the cursor placement from being reset to0
.
rl.prompt()
方法将配置为 prompt
的 InterfaceConstructor
实例写入 output
中的新行,以便为用户提供用于提供输入的新位置。
¥The rl.prompt()
method writes the InterfaceConstructor
instances configured
prompt
to a new line in output
in order to provide a user with a new
location at which to provide input.
当调用时,如果 rl.prompt()
流已暂停,则 rl.prompt()
将恢复 input
流。
¥When called, rl.prompt()
will resume the input
stream if it has been
paused.
如果 InterfaceConstructor
是在 output
设置为 null
或 undefined
的情况下创建的,则不会写入提示。
¥If the InterfaceConstructor
was created with output
set to null
or
undefined
the prompt is not written.
rl.resume()
#
如果 input
流已暂停,则 rl.resume()
方法会恢复该流。
¥The rl.resume()
method resumes the input
stream if it has been paused.
rl.setPrompt(prompt)
#
prompt
<string>
rl.setPrompt()
方法设置了在调用 rl.prompt()
时将写入 output
的提示。
¥The rl.setPrompt()
method sets the prompt that will be written to output
whenever rl.prompt()
is called.
rl.getPrompt()
#
rl.getPrompt()
方法返回 rl.prompt()
使用的当前提示。
¥The rl.getPrompt()
method returns the current prompt used by rl.prompt()
.
rl.write(data[, key])
#
rl.write()
方法会将 data
或由 key
标识的键序列写入 output
。仅当 output
是 TTY 文本终端时才支持 key
参数。有关组合键列表,请参阅 TTY 键绑定。
¥The rl.write()
method will write either data
or a key sequence identified
by key
to the output
. The key
argument is supported only if output
is
a TTY text terminal. See TTY keybindings for a list of key
combinations.
如果指定了 key
,则忽略 data
。
¥If key
is specified, data
is ignored.
当调用时,如果 rl.write()
流已暂停,则 rl.write()
将恢复 input
流。
¥When called, rl.write()
will resume the input
stream if it has been
paused.
如果 InterfaceConstructor
是在 output
设置为 null
或 undefined
的情况下创建的,则不会写入 data
和 key
。
¥If the InterfaceConstructor
was created with output
set to null
or
undefined
the data
and key
are not written.
rl.write('Delete this!');
// Simulate Ctrl+U to delete the line written previously
rl.write(null, { ctrl: true, name: 'u' });
rl.write()
方法会将数据写入 readline
Interface
的 input
,就好像它是由用户提供的一样。
¥The rl.write()
method will write the data to the readline
Interface
's
input
as if it were provided by the user.
rl[Symbol.asyncIterator]()
#
-
¥Returns: <AsyncIterator>
创建 AsyncIterator
对象,该对象遍历输入流中的每一行作为字符串。此方法允许通过 for await...of
循环异步迭代 InterfaceConstructor
对象。
¥Create an AsyncIterator
object that iterates through each line in the input
stream as a string. This method allows asynchronous iteration of
InterfaceConstructor
objects through for await...of
loops.
输入流中的错误不会被转发。
¥Errors in the input stream are not forwarded.
如果循环以 break
、throw
或 return
终止,则将调用 rl.close()
。换句话说,迭代 InterfaceConstructor
将始终完全消费输入流。
¥If the loop is terminated with break
, throw
, or return
,
rl.close()
will be called. In other words, iterating over a
InterfaceConstructor
will always consume the input stream fully.
性能无法与传统的 'line'
事件 API 相提并论。对于性能敏感的应用,请改用 'line'
。
¥Performance is not on par with the traditional 'line'
event API. Use 'line'
instead for performance-sensitive applications.
async function processLineByLine() {
const rl = readline.createInterface({
// ...
});
for await (const line of rl) {
// Each line in the readline input will be successively available here as
// `line`.
}
}
readline.createInterface()
将在调用后开始使用输入流。在接口创建和异步迭代之间进行异步操作可能会导致丢失行。
¥readline.createInterface()
will start to consume the input stream once
invoked. Having asynchronous operations between interface creation and
asynchronous iteration may result in missed lines.
rl.line
#
节点正在处理的当前输入数据。
¥The current input data being processed by node.
这可用于从 TTY 流中收集输入以检索迄今为止(在 line
事件触发之前)已处理的当前值。一旦触发 line
事件,则此属性将是空字符串。
¥This can be used when collecting input from a TTY stream to retrieve the
current value that has been processed thus far, prior to the line
event
being emitted. Once the line
event has been emitted, this property will
be an empty string.
请注意,如果 rl.cursor
也不受控制,则在实例运行时修改该值可能会产生意想不到的后果。
¥Be aware that modifying the value during the instance runtime may have
unintended consequences if rl.cursor
is not also controlled.
如果不使用 TTY 流进行输入,请使用 'line'
事件。
¥If not using a TTY stream for input, use the 'line'
event.
一个可能的用例如下:
¥One possible use case would be as follows:
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
#
相对于 rl.line
的光标位置。
¥The cursor position relative to rl.line
.
当从 TTY 流读取输入时,这将跟踪当前光标在输入字符串中的位置。光标的位置决定了在处理输入时将被修改的输入字符串部分,以及将渲染终端插入符号的列。
¥This will track where the current cursor lands in the input string, when reading input from a TTY stream. The position of cursor determines the portion of the input string that will be modified as input is processed, as well as the column where the terminal caret will be rendered.
rl.getCursorPos()
#
返回光标相对于输入提示 + 字符串的实际位置。长输入(换行)字符串以及多行提示都包含在计算中。
¥Returns the real position of the cursor in relation to the input prompt + string. Long input (wrapping) strings, as well as multiple line prompts are included in the calculations.
Promise API#
¥Stability: 1 - Experimental
类:readlinePromises.Interface
#
¥Class: readlinePromises.Interface
readlinePromises.Interface
类的实例是使用 readlinePromises.createInterface()
方法构造的。每个实例都与单个 input
可读 流和单个 output
可写 流相关联。output
流用于打印到达并从 input
流中读取的用户输入的提示。
¥Instances of the readlinePromises.Interface
class are constructed using the
readlinePromises.createInterface()
method. Every instance is associated with a
single input
Readable stream and a single output
Writable stream.
The output
stream is used to print prompts for user input that arrives on,
and is read from, the input
stream.
rl.question(query[, options])
#
-
query
<string> 要写入output
的语句或查询,位于提示之前。¥
query
<string> A statement or query to write tooutput
, prepended to the prompt. -
options
<Object>-
signal
<AbortSignal> 可选择允许使用AbortSignal
取消question()
。¥
signal
<AbortSignal> Optionally allows thequestion()
to be canceled using anAbortSignal
.
-
-
返回:<Promise> 使用用户响应
query
的输入履行的 promise。¥Returns: <Promise> A promise that is fulfilled with the user's input in response to the
query
.
rl.question()
方法通过将 query
写入 output
来显示 query
,等待在 input
上提供用户输入,然后调用 callback
函数,将提供的输入作为第一个参数传入。
¥The rl.question()
method displays the query
by writing it to the output
,
waits for user input to be provided on input
, then invokes the callback
function passing the provided input as the first argument.
当调用时,如果 rl.question()
流已暂停,则 rl.question()
将恢复 input
流。
¥When called, rl.question()
will resume the input
stream if it has been
paused.
如果 readlinePromises.Interface
是在 output
设置为 null
或 undefined
的情况下创建的,则不会写入 query
。
¥If the readlinePromises.Interface
was created with output
set to null
or
undefined
the query
is not written.
如果问题在 rl.close()
之后被调用,则它返回被拒绝的 promise。
¥If the question is called after rl.close()
, it returns a rejected promise.
用法示例:
¥Example usage:
const answer = await rl.question('What is your favorite food? ');
console.log(`Oh, so your favorite food is ${answer}`);
使用 AbortSignal
取消问题。
¥Using an AbortSignal
to cancel a question.
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
#
¥Class: readlinePromises.Readline
new readlinePromises.Readline(stream[, options])
#
-
stream
<stream.Writable> TTY 流。¥
stream
<stream.Writable> A TTY stream. -
options
<Object>
rl.clearLine(dir)
#
-
dir
<integer>-
-1
:从光标向左¥
-1
: to the left from cursor -
1
:从光标向右¥
1
: to the right from cursor -
0
:整行¥
0
: the entire line
-
-
返回:自身
¥Returns: this
rl.clearLine()
方法在待处理动作的内部列表中添加一个动作,该动作在 dir
标识的指定方向上清除关联 stream
的当前行。调用 rl.commit()
看看这个方法的效果,除非 autoCommit: true
传给了构造函数。
¥The rl.clearLine()
method adds to the internal list of pending action an
action that clears current line of the associated stream
in a specified
direction identified by dir
.
Call rl.commit()
to see the effect of this method, unless autoCommit: true
was passed to the constructor.
rl.clearScreenDown()
#
-
返回:自身
¥Returns: this
rl.clearScreenDown()
方法向待处理动作的内部列表添加一个动作,该动作从光标向下的当前位置清除关联流。调用 rl.commit()
看看这个方法的效果,除非 autoCommit: true
传给了构造函数。
¥The rl.clearScreenDown()
method adds to the internal list of pending action an
action that clears the associated stream from the current position of the
cursor down.
Call rl.commit()
to see the effect of this method, unless autoCommit: true
was passed to the constructor.
rl.commit()
#
rl.commit()
方法将所有待处理的操作发送到关联的 stream
并清除待处理操作的内部列表。
¥The rl.commit()
method sends all the pending actions to the associated
stream
and clears the internal list of pending actions.
rl.cursorTo(x[, y])
#
rl.cursorTo()
方法向待处理动作的内部列表添加一个动作,该动作将光标移动到相关 stream
中指定的位置。调用 rl.commit()
看看这个方法的效果,除非 autoCommit: true
传给了构造函数。
¥The rl.cursorTo()
method adds to the internal list of pending action an action
that moves cursor to the specified position in the associated stream
.
Call rl.commit()
to see the effect of this method, unless autoCommit: true
was passed to the constructor.
rl.moveCursor(dx, dy)
#
rl.moveCursor()
方法向待处理操作的内部列表添加一个操作,该操作将光标相对于关联的 stream
中的当前位置移动。调用 rl.commit()
看看这个方法的效果,除非 autoCommit: true
传给了构造函数。
¥The rl.moveCursor()
method adds to the internal list of pending action an
action that moves the cursor relative to its current position in the
associated stream
.
Call rl.commit()
to see the effect of this method, unless autoCommit: true
was passed to the constructor.
rl.rollback()
#
-
返回:自身
¥Returns: this
rl.rollback
方法清除内部待处理操作列表,而不将其发送到关联的 stream
。
¥The rl.rollback
methods clears the internal list of pending actions without
sending it to the associated stream
.
readlinePromises.createInterface(options)
#
-
options
<Object>-
input
<stream.Readable> 要收听的 可读 流。此选项是必需的。¥
input
<stream.Readable> The Readable stream to listen to. This option is required. -
output
<stream.Writable> 要写入 readline 数据的 可写 流。¥
output
<stream.Writable> The Writable stream to write readline data to. -
completer
<Function> 可选的用于制表符自动补全的函数。¥
completer
<Function> An optional function used for Tab autocompletion. -
terminal
<boolean>true
(如果input
和output
流应被视为 TTY,并且写入了 ANSI/VT100 转义码)。默认值:在实例化时检查output
流上的isTTY
。¥
terminal
<boolean>true
if theinput
andoutput
streams should be treated like a TTY, and have ANSI/VT100 escape codes written to it. Default: checkingisTTY
on theoutput
stream upon instantiation. -
history
<string[]> 历史行的初始列表。仅当terminal
由用户或内部的output
检查设置为true
时,此选项才有意义,否则历史缓存机制根本不会初始化。默认值:[]
。¥
history
<string[]> Initial list of history lines. This option makes sense only ifterminal
is set totrue
by the user or by an internaloutput
check, otherwise the history caching mechanism is not initialized at all. Default:[]
. -
historySize
<number> 保留的最大历史行数。要禁用历史记录,则将此值设置为0
。仅当terminal
由用户或内部的output
检查设置为true
时,此选项才有意义,否则历史缓存机制根本不会初始化。默认值:30
。¥
historySize
<number> Maximum number of history lines retained. To disable the history set this value to0
. This option makes sense only ifterminal
is set totrue
by the user or by an internaloutput
check, otherwise the history caching mechanism is not initialized at all. Default:30
. -
removeHistoryDuplicates
<boolean> 如果为true
,则当添加到历史列表的新输入行与旧输入行重复时,这将从列表中删除旧行。默认值:false
。¥
removeHistoryDuplicates
<boolean> Iftrue
, when a new input line added to the history list duplicates an older one, this removes the older line from the list. Default:false
. -
prompt
<string> 要使用的提示字符串。默认值:'> '
。¥
prompt
<string> The prompt string to use. Default:'> '
. -
crlfDelay
<number> 如果\r
和\n
之间的延迟超过crlfDelay
毫秒,则\r
和\n
都将被视为单独的行尾输入。crlfDelay
将被强制为不小于100
的数字。它可以设置为Infinity
,在这种情况下,\r
后跟\n
将始终被视为单个换行符(这对于带有\r\n
行分隔符的 读取文件 可能是合理的)。默认值:100
。¥
crlfDelay
<number> If the delay between\r
and\n
exceedscrlfDelay
milliseconds, both\r
and\n
will be treated as separate end-of-line input.crlfDelay
will be coerced to a number no less than100
. It can be set toInfinity
, in which case\r
followed by\n
will always be considered a single newline (which may be reasonable for reading files with\r\n
line delimiter). Default:100
. -
escapeCodeTimeout
<number>readlinePromises
将等待字符的时长(当以毫秒为单位读取不明确的键序列时,既可以使用目前读取的输入形成完整的键序列,又可以采用额外的输入来完成更长的键序列)。默认值:500
。¥
escapeCodeTimeout
<number> The durationreadlinePromises
will wait for a character (when reading an ambiguous key sequence in milliseconds one that can both form a complete key sequence using the input read so far and can take additional input to complete a longer key sequence). Default:500
. -
tabSize
<integer> 一个制表符等于的空格数(最小为 1)。默认值:8
。¥
tabSize
<integer> The number of spaces a tab is equal to (minimum 1). Default:8
.
-
-
返回:<readlinePromises.Interface>
¥Returns: <readlinePromises.Interface>
readlinePromises.createInterface()
方法创建新的 readlinePromises.Interface
实例。
¥The readlinePromises.createInterface()
method creates a new readlinePromises.Interface
instance.
const readlinePromises = require('node:readline/promises');
const rl = readlinePromises.createInterface({
input: process.stdin,
output: process.stdout,
});
一旦创建了 readlinePromises.Interface
实例,则最常见的场景就是监听 'line'
事件:
¥Once the readlinePromises.Interface
instance is created, the most common case
is to listen for the 'line'
event:
rl.on('line', (line) => {
console.log(`Received: ${line}`);
});
如果此实例的 terminal
是 true
,则如果它定义了 output.columns
属性,并且如果或当列发生变化时(process.stdout
会当其是终端时自动执行此操作)在 output
上触发 'resize'
事件,则 output
流将获得最佳的兼容性。
¥If terminal
is true
for this instance then the output
stream will get
the best compatibility if it defines an output.columns
property and emits
a 'resize'
event on the output
if or when the columns ever change
(process.stdout
does this automatically when it is a TTY).
completer
函数的使用#
¥Use of the completer
function
completer
函数将用户输入的当前行作为参数,并返回包含 2 个条目的 Array
:
¥The completer
function takes the current line entered by the user
as an argument, and returns an Array
with 2 entries:
-
使用匹配条目的
Array
补全。¥An
Array
with matching entries for the completion. -
用于匹配的子字符串。
¥The substring that was used for the matching.
例如:[[substr1, substr2, ...], originalsubstring]
。
¥For instance: [[substr1, substr2, ...], originalsubstring]
.
function completer(line) {
const completions = '.help .error .exit .quit .q'.split(' ');
const hits = completions.filter((c) => c.startsWith(line));
// Show all completions if none found
return [hits.length ? hits : completions, line];
}
completer
函数也可以返回 <Promise>,或者是异步的:
¥The completer
function can also return a <Promise>, or be asynchronous:
async function completer(linePartial) {
await someAsyncWork();
return [['123'], linePartial];
}
回调接口#
¥Callback API
类:readline.Interface
#
¥Class: readline.Interface
readline.Interface
类的实例是使用 readline.createInterface()
方法构造的。每个实例都与单个 input
可读 流和单个 output
可写 流相关联。output
流用于打印到达并从 input
流中读取的用户输入的提示。
¥Instances of the readline.Interface
class are constructed using the
readline.createInterface()
method. Every instance is associated with a
single input
Readable stream and a single output
Writable stream.
The output
stream is used to print prompts for user input that arrives on,
and is read from, the input
stream.
rl.question(query[, options], callback)
#
-
query
<string> 要写入output
的语句或查询,位于提示之前。¥
query
<string> A statement or query to write tooutput
, prepended to the prompt. -
options
<Object>-
signal
<AbortSignal> 可选择允许使用AbortController
取消question()
。¥
signal
<AbortSignal> Optionally allows thequestion()
to be canceled using anAbortController
.
-
-
callback
<Function> 使用用户输入调用的回调函数以响应query
。¥
callback
<Function> A callback function that is invoked with the user's input in response to thequery
.
rl.question()
方法通过将 query
写入 output
来显示 query
,等待在 input
上提供用户输入,然后调用 callback
函数,将提供的输入作为第一个参数传入。
¥The rl.question()
method displays the query
by writing it to the output
,
waits for user input to be provided on input
, then invokes the callback
function passing the provided input as the first argument.
当调用时,如果 rl.question()
流已暂停,则 rl.question()
将恢复 input
流。
¥When called, rl.question()
will resume the input
stream if it has been
paused.
如果 readline.Interface
是在 output
设置为 null
或 undefined
的情况下创建的,则不会写入 query
。
¥If the readline.Interface
was created with output
set to null
or
undefined
the query
is not written.
传给 rl.question()
的 callback
函数不遵循接受 Error
对象或 null
作为第一个参数的典型模式。以提供的答案作为唯一参数调用 callback
。
¥The callback
function passed to rl.question()
does not follow the typical
pattern of accepting an Error
object or null
as the first argument.
The callback
is called with the provided answer as the only argument.
在 rl.close()
之后调用 rl.question()
会报错。
¥An error will be thrown if calling rl.question()
after rl.close()
.
用法示例:
¥Example usage:
rl.question('What is your favorite food? ', (answer) => {
console.log(`Oh, so your favorite food is ${answer}`);
});
使用 AbortController
取消问题。
¥Using an AbortController
to cancel a question.
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])
#
-
stream
<stream.Writable> -
dir
<number>-
-1
:从光标向左¥
-1
: to the left from cursor -
1
:从光标向右¥
1
: to the right from cursor -
0
:整行¥
0
: the entire line
-
-
callback
<Function> 操作完成后调用。¥
callback
<Function> Invoked once the operation completes. -
返回:<boolean>
false
(如果stream
希望调用代码在继续写入附加数据之前等待'drain'
事件触发);否则true
。¥Returns: <boolean>
false
ifstream
wishes for the calling code to wait for the'drain'
event to be emitted before continuing to write additional data; otherwisetrue
.
readline.clearLine()
方法在 dir
标识的指定方向上清除给定 TTY 流的当前行。
¥The readline.clearLine()
method clears current line of given TTY stream
in a specified direction identified by dir
.
readline.clearScreenDown(stream[, callback])
#
-
stream
<stream.Writable> -
callback
<Function> 操作完成后调用。¥
callback
<Function> Invoked once the operation completes. -
返回:<boolean>
false
(如果stream
希望调用代码在继续写入附加数据之前等待'drain'
事件触发);否则true
。¥Returns: <boolean>
false
ifstream
wishes for the calling code to wait for the'drain'
event to be emitted before continuing to write additional data; otherwisetrue
.
readline.clearScreenDown()
方法从光标的当前位置向下清除给定的 TTY 流。
¥The readline.clearScreenDown()
method clears the given TTY stream from
the current position of the cursor down.
readline.createInterface(options)
#
-
options
<Object>-
input
<stream.Readable> 要收听的 可读 流。此选项是必需的。¥
input
<stream.Readable> The Readable stream to listen to. This option is required. -
output
<stream.Writable> 要写入 readline 数据的 可写 流。¥
output
<stream.Writable> The Writable stream to write readline data to. -
completer
<Function> 可选的用于制表符自动补全的函数。¥
completer
<Function> An optional function used for Tab autocompletion. -
terminal
<boolean>true
(如果input
和output
流应被视为 TTY,并且写入了 ANSI/VT100 转义码)。默认值:在实例化时检查output
流上的isTTY
。¥
terminal
<boolean>true
if theinput
andoutput
streams should be treated like a TTY, and have ANSI/VT100 escape codes written to it. Default: checkingisTTY
on theoutput
stream upon instantiation. -
history
<string[]> 历史行的初始列表。仅当terminal
由用户或内部的output
检查设置为true
时,此选项才有意义,否则历史缓存机制根本不会初始化。默认值:[]
。¥
history
<string[]> Initial list of history lines. This option makes sense only ifterminal
is set totrue
by the user or by an internaloutput
check, otherwise the history caching mechanism is not initialized at all. Default:[]
. -
historySize
<number> 保留的最大历史行数。要禁用历史记录,则将此值设置为0
。仅当terminal
由用户或内部的output
检查设置为true
时,此选项才有意义,否则历史缓存机制根本不会初始化。默认值:30
。¥
historySize
<number> Maximum number of history lines retained. To disable the history set this value to0
. This option makes sense only ifterminal
is set totrue
by the user or by an internaloutput
check, otherwise the history caching mechanism is not initialized at all. Default:30
. -
removeHistoryDuplicates
<boolean> 如果为true
,则当添加到历史列表的新输入行与旧输入行重复时,这将从列表中删除旧行。默认值:false
。¥
removeHistoryDuplicates
<boolean> Iftrue
, when a new input line added to the history list duplicates an older one, this removes the older line from the list. Default:false
. -
prompt
<string> 要使用的提示字符串。默认值:'> '
。¥
prompt
<string> The prompt string to use. Default:'> '
. -
crlfDelay
<number> 如果\r
和\n
之间的延迟超过crlfDelay
毫秒,则\r
和\n
都将被视为单独的行尾输入。crlfDelay
将被强制为不小于100
的数字。它可以设置为Infinity
,在这种情况下,\r
后跟\n
将始终被视为单个换行符(这对于带有\r\n
行分隔符的 读取文件 可能是合理的)。默认值:100
。¥
crlfDelay
<number> If the delay between\r
and\n
exceedscrlfDelay
milliseconds, both\r
and\n
will be treated as separate end-of-line input.crlfDelay
will be coerced to a number no less than100
. It can be set toInfinity
, in which case\r
followed by\n
will always be considered a single newline (which may be reasonable for reading files with\r\n
line delimiter). Default:100
. -
escapeCodeTimeout
<number>readline
将等待字符的时长(当以毫秒为单位读取不明确的键序列时,既可以使用目前读取的输入形成完整的键序列,又可以采用额外的输入来完成更长的键序列)。默认值:500
。¥
escapeCodeTimeout
<number> The durationreadline
will wait for a character (when reading an ambiguous key sequence in milliseconds one that can both form a complete key sequence using the input read so far and can take additional input to complete a longer key sequence). Default:500
. -
tabSize
<integer> 一个制表符等于的空格数(最小为 1)。默认值:8
。¥
tabSize
<integer> The number of spaces a tab is equal to (minimum 1). Default:8
. -
signal
<AbortSignal> 允许使用中止信号关闭接口。中止信号将在内部调用接口上的close
。¥
signal
<AbortSignal> Allows closing the interface using an AbortSignal. Aborting the signal will internally callclose
on the interface.
-
-
¥Returns: <readline.Interface>
readline.createInterface()
方法创建新的 readline.Interface
实例。
¥The readline.createInterface()
method creates a new readline.Interface
instance.
const readline = require('node:readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
一旦创建了 readline.Interface
实例,则最常见的场景就是监听 'line'
事件:
¥Once the readline.Interface
instance is created, the most common case is to
listen for the 'line'
event:
rl.on('line', (line) => {
console.log(`Received: ${line}`);
});
如果此实例的 terminal
是 true
,则如果它定义了 output.columns
属性,并且如果或当列发生变化时(process.stdout
会当其是终端时自动执行此操作)在 output
上触发 'resize'
事件,则 output
流将获得最佳的兼容性。
¥If terminal
is true
for this instance then the output
stream will get
the best compatibility if it defines an output.columns
property and emits
a 'resize'
event on the output
if or when the columns ever change
(process.stdout
does this automatically when it is a TTY).
当使用 stdin
作为输入创建 readline.Interface
时,程序将不会终止,直到它收到 EOF 字符。要在不等待用户输入的情况下退出,则调用 process.stdin.unref()
。
¥When creating a readline.Interface
using stdin
as input, the program
will not terminate until it receives an EOF character. To exit without
waiting for user input, call process.stdin.unref()
.
completer
函数的使用#
¥Use of the completer
function
completer
函数将用户输入的当前行作为参数,并返回包含 2 个条目的 Array
:
¥The completer
function takes the current line entered by the user
as an argument, and returns an Array
with 2 entries:
-
使用匹配条目的
Array
补全。¥An
Array
with matching entries for the completion. -
用于匹配的子字符串。
¥The substring that was used for the matching.
例如:[[substr1, substr2, ...], originalsubstring]
。
¥For instance: [[substr1, substr2, ...], originalsubstring]
.
function completer(line) {
const completions = '.help .error .exit .quit .q'.split(' ');
const hits = completions.filter((c) => c.startsWith(line));
// Show all completions if none found
return [hits.length ? hits : completions, line];
}
如果 completer
函数接受两个参数,则可以异步地调用它:
¥The completer
function can be called asynchronously if it accepts two
arguments:
function completer(linePartial, callback) {
callback(null, [['123'], linePartial]);
}
readline.cursorTo(stream, x[, y][, callback])
#
-
stream
<stream.Writable> -
x
<number> -
y
<number> -
callback
<Function> 操作完成后调用。¥
callback
<Function> Invoked once the operation completes. -
返回:<boolean>
false
(如果stream
希望调用代码在继续写入附加数据之前等待'drain'
事件触发);否则true
。¥Returns: <boolean>
false
ifstream
wishes for the calling code to wait for the'drain'
event to be emitted before continuing to write additional data; otherwisetrue
.
readline.cursorTo()
方法将光标移动到给定的 TTY stream
中的指定位置。
¥The readline.cursorTo()
method moves cursor to the specified position in a
given TTY stream
.
readline.moveCursor(stream, dx, dy[, callback])
#
-
stream
<stream.Writable> -
dx
<number> -
dy
<number> -
callback
<Function> 操作完成后调用。¥
callback
<Function> Invoked once the operation completes. -
返回:<boolean>
false
(如果stream
希望调用代码在继续写入附加数据之前等待'drain'
事件触发);否则true
。¥Returns: <boolean>
false
ifstream
wishes for the calling code to wait for the'drain'
event to be emitted before continuing to write additional data; otherwisetrue
.
readline.moveCursor()
方法将光标相对于其在给定 TTY stream
中的当前位置移动。
¥The readline.moveCursor()
method moves the cursor relative to its current
position in a given TTY stream
.
readline.emitKeypressEvents(stream[, interface])
#
-
stream
<stream.Readable> -
interface
<readline.InterfaceConstructor>
readline.emitKeypressEvents()
方法使给定的 可读 流开始触发与接收到的输入相对应的 'keypress'
事件。
¥The readline.emitKeypressEvents()
method causes the given Readable
stream to begin emitting 'keypress'
events corresponding to received input.
可选地,interface
指定 readline.Interface
实例,当检测到复制粘贴输入时禁用自动补齐。
¥Optionally, interface
specifies a readline.Interface
instance for which
autocompletion is disabled when copy-pasted input is detected.
如果 stream
是 TTY,则它必须处于原始模式。
¥If the stream
is a TTY, then it must be in raw mode.
如果 input
是终端,则它会被其 input
上的任何逐行读取实例自动调用。关闭 readline
实例不会阻止 input
触发 'keypress'
事件。
¥This is automatically called by any readline instance on its input
if the
input
is a terminal. Closing the readline
instance does not stop
the input
from emitting 'keypress'
events.
readline.emitKeypressEvents(process.stdin);
if (process.stdin.isTTY)
process.stdin.setRawMode(true);
示例:微型命令行接口#
¥Example: Tiny CLI
下面的例子说明了使用 readline.Interface
类来实现一个微型的命令行接口:
¥The following example illustrates the use of readline.Interface
class to
implement a small command-line interface:
const readline = require('node:readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
prompt: 'OHAI> ',
});
rl.prompt();
rl.on('line', (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', () => {
console.log('Have a great day!');
process.exit(0);
});
示例:逐行读取文件流#
¥Example: Read file stream line-by-Line
readline
的一个常见用例是每次一行地消费输入文件。最简单的方式是利用 fs.ReadStream
API 和 for await...of
循环:
¥A common use case for readline
is to consume an input file one line at a
time. The easiest way to do so is leveraging the fs.ReadStream
API as
well as a for await...of
loop:
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,
});
// Note: we use the crlfDelay option to recognize all instances of CR LF
// ('\r\n') in input.txt as a single line break.
for await (const line of rl) {
// Each line in input.txt will be successively available here as `line`.
console.log(`Line from file: ${line}`);
}
}
processLineByLine();
或者,可以使用 'line'
事件:
¥Alternatively, one could use the 'line'
event:
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
流量和速度都必不可少,则可以应用混合方法:
¥Currently, for await...of
loop can be a bit slower. If async
/ await
flow and speed are both essential, a mixed approach can be applied:
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) => {
// Process the line.
});
await once(rl, 'close');
console.log('File processed.');
} catch (err) {
console.error(err);
}
})();
TTY 键绑定#
¥TTY keybindings
快捷键 | 描述 | 注意事项 |
---|---|---|
Ctrl+Shift+Backspace | 删除行左 | 不适用于 Linux、Mac 和 Windows |
Ctrl+Shift+Delete | 删除行右 | 不适用于 Mac |
Ctrl+C | 触发 SIGINT 或关闭 readline 实例 |
|
Ctrl+H | 删除左边 | |
Ctrl+D | 如果当前行为空或 EOF,则向右删除或关闭逐行读取实例 | 不适用于 Windows |
Ctrl+U | 从当前位置删除到行首 | |
Ctrl+K | 从当前位置删除到行尾 | |
Ctrl+Y | Yank (Recall) 之前删除的文本 | 仅适用于通过 Ctrl+U 或 Ctrl+K 删除的文本 |
Meta+Y | 在先前删除的文本之间循环 | 仅当最后一次击键为 Ctrl+Y 或 Meta+Y 时可用 |
Ctrl+A | 转到行首 | |
Ctrl+E | 跳到行尾 | |
Ctrl+B | 后退一个字符 | |
Ctrl+F | 前进一个字符 | |
Ctrl+L | 清屏 | |
Ctrl+N | 下一个历史子项 | |
Ctrl+P | 上一个历史子项 | |
Ctrl+- | 撤消之前的更改 | 任何触发键代码 XSPACE0x1F 的击键都会执行此操作。在许多终端中,例如 xterm ,这绑定到 Ctrl+-。 |
Ctrl+XSPACE6 | 重做之前的更改 | 许多终端没有默认的重做击键。我们选择密钥代码 XSPACE0x1E 来执行重做。在 xterm 中,默认绑定到 Ctrl+XSPACE6。 |
Ctrl+Z | 将正在运行的进程移至后台。键入
fg 并按 Enter 返回。 |
不适用于 Windows |
Ctrl+W 或 Ctrl+Backspace | 向后删除到单词边界 | Ctrl+Backspace 不适用于 Linux、Mac 和 Windows |
Ctrl+Delete | 向前删除到单词边界 | 不适用于 Mac |
Ctrl+Left arrow 或 Meta+B | 左边的单词 | Ctrl+Left arrow 不适用于 Mac |
Ctrl+Right arrow 或 Meta+F | 右边的单词 | Ctrl+Right arrow 不适用于 Mac |
Meta+D 或 Meta+Delete | 删除右边的单词 | Meta+Delete 不适用于 Windows |
Meta+Backspace | 删除左边的单词 | 不适用于 Mac |