readline
Модуль node:readline предоставляет интерфейс для построчного чтения данных из потока Readable (например, process.stdin).
Для использования API на основе промисов:
import * as readline from 'node:readline/promises';
Для использования API с обратными вызовами и синхронного API:
import * as readline from '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();
После вызова этого кода приложение Node.js не завершится, пока не будет закрыт readline.Interface, поскольку интерфейс ожидает получения данных из потока input.
Использование в Deno
import * as mod from "node:readline";
класс Interface
Использование в Deno
import { Interface } from "node:readline";
Экземпляры класса readline.Interface создаются с помощью метода readline.createInterface(). Каждый экземпляр связан с одним потоком input Readable и одним потоком output Writable. Поток output используется для вывода приглашений к вводу данных пользователем, которые поступают из потока input и считываются из него.
Конструкторы
Interface(
input: ReadableStream,
output?: WritableStream,
completer?: Completer | AsyncCompleter,
terminal?: boolean,
) ПРИМЕЧАНИЕ: Согласно документации:
Экземпляры класса
readline.Interfaceсоздаются с помощью методаreadline.createInterface().
Interface(options: ReadLineOptions) ПРИМЕЧАНИЕ: Согласно документации:
Экземпляры класса
readline.Interfaceсоздаются с помощью методаreadline.createInterface().
Свойства
cursor: number Позиция курсора относительно rl.line.
При чтении ввода из потока TTY это свойство отслеживает положение текущего курсора в строке ввода. Позиция курсора определяет часть строки ввода, которая будет изменена при обработке ввода, а также столбец, в котором будет отображаться курсор терминала.
line: string Текущие входные данные, обрабатываемые Node.js.
При сборе данных из потока 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();
});
terminal: boolean Методы
[Symbol.asyncIterator](): AsyncIterator<string> addListener(
event: string,
listener: (...args: any[]) => void,
): this events.EventEmitter
- close
- line
- pause
- resume
- SIGCONT
- SIGINT
- SIGTSTP
- history
addListener(
event: "close",
listener: () => void,
): this addListener(
event: "line",
listener: (input: string) => void,
): this addListener(
event: "pause",
listener: () => void,
): this addListener(
event: "resume",
listener: () => void,
): this addListener(
event: "SIGCONT",
listener: () => void,
): this addListener(
event: "SIGINT",
listener: () => void,
): this addListener(
event: "SIGTSTP",
listener: () => void,
): this addListener(
event: "history",
listener: (history: string[]) => void,
): this close(): void Метод rl.close() закрывает экземпляр Interface и освобождает управление потоками input и output. При вызове генерируется событие 'close'.
Вызов rl.close() не останавливает немедленно генерацию других событий (в том числе 'line') экземпляром Interface.
emit(
event: string | symbol,
...args: any[],
): boolean emit(event: "close"): boolean emit(
event: "line",
input: string,
): boolean emit(event: "pause"): boolean emit(event: "resume"): boolean emit(event: "SIGCONT"): boolean emit(event: "SIGINT"): boolean emit(event: "SIGTSTP"): boolean emit(
event: "history",
history: string[],
): boolean Возвращает фактическую позицию курсора относительно приглашения и строки ввода. При расчёте учитываются длинные строки ввода с переносами, а также многострочные приглашения.
getPrompt(): string Метод rl.getPrompt() возвращает текущее приглашение, используемое rl.prompt().
on(
event: string,
listener: (...args: any[]) => void,
): this on(
event: "close",
listener: () => void,
): this on(
event: "line",
listener: (input: string) => void,
): this on(
event: "pause",
listener: () => void,
): this on(
event: "resume",
listener: () => void,
): this on(
event: "SIGCONT",
listener: () => void,
): this on(
event: "SIGINT",
listener: () => void,
): this on(
event: "SIGTSTP",
listener: () => void,
): this on(
event: "history",
listener: (history: string[]) => void,
): this once(
event: string,
listener: (...args: any[]) => void,
): this once(
event: "close",
listener: () => void,
): this once(
event: "line",
listener: (input: string) => void,
): this once(
event: "pause",
listener: () => void,
): this once(
event: "resume",
listener: () => void,
): this once(
event: "SIGCONT",
listener: () => void,
): this once(
event: "SIGINT",
listener: () => void,
): this once(
event: "SIGTSTP",
listener: () => void,
): this once(
event: "history",
listener: (history: string[]) => void,
): this pause(): this Метод rl.pause() приостанавливает поток input, позволяя при необходимости возобновить его позднее.
Вызов rl.pause() не приостанавливает немедленно генерацию других событий (в том числе 'line') экземпляром Interface.
prependListener(
event: string,
listener: (...args: any[]) => void,
): this prependListener(
event: "close",
listener: () => void,
): this prependListener(
event: "line",
listener: (input: string) => void,
): this prependListener(
event: "pause",
listener: () => void,
): this prependListener(
event: "resume",
listener: () => void,
): this prependListener(
event: "SIGCONT",
listener: () => void,
): this prependListener(
event: "SIGINT",
listener: () => void,
): this prependListener(
event: "SIGTSTP",
listener: () => void,
): this prependListener(
event: "history",
listener: (history: string[]) => void,
): this prependOnceListener(
event: string,
listener: (...args: any[]) => void,
): this prependOnceListener(
event: "close",
listener: () => void,
): this prependOnceListener(
event: "line",
listener: (input: string) => void,
): this prependOnceListener(
event: "pause",
listener: () => void,
): this prependOnceListener(
event: "resume",
listener: () => void,
): this prependOnceListener(
event: "SIGCONT",
listener: () => void,
): this prependOnceListener(
event: "SIGINT",
listener: () => void,
): this prependOnceListener(
event: "SIGTSTP",
listener: () => void,
): this prependOnceListener(
event: "history",
listener: (history: string[]) => void,
): this prompt(preserveCursor?: boolean): void Метод rl.prompt() выводит настроенное для экземпляра Interface приглашениеprompt в новую строку потока output, чтобы предоставить пользователю новое место для ввода данных.
При вызове rl.prompt() возобновит поток input, если он был приостановлен.
Если Interface был создан с параметром output, установленным в значение null или undefined, приглашение не выводится.
question(
query: string,
callback: (answer: string) => void,
): void Метод rl.question() отображает query, выводя его в поток output, ожидает ввода данных пользователем в input, а затем вызывает функцию callback, передавая введённые данные в качестве первого аргумента.
При вызове rl.question() возобновит поток input, если он был приостановлен.
Если Interface был создан с параметром output, установленным в значение null или undefined, query не выводится.
Функция callback, переданная в rl.question(), не следует обычному шаблону, при котором первым аргументом принимается объект Error или null. Функция callback вызывается, и единственным аргументом ей передаётся предоставленный ответ.
При вызове rl.question() после rl.close() будет выброшена ошибка.
Пример использования:
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);
resume(): this Метод rl.resume() возобновляет поток input, если он был приостановлен.
setPrompt(prompt: string): void Метод rl.setPrompt() задаёт приглашение, которое будет выводиться в output при каждом вызове rl.prompt().
Метод rl.write() записывает в output либо data, либо последовательность клавиш, определяемую key. Аргумент key поддерживается только в том случае, если output — это текстовый терминал TTY. Список сочетаний клавиш см. в TTY keybindings.
Если указан key, data игнорируется.
При вызове rl.write() возобновит поток input, если он был приостановлен.
Если Interface был создан с параметром output, установленным в значение null или undefined, data и key не выводятся.
rl.write('Delete this!');
// Simulate Ctrl+U to delete the line written previously
rl.write(null, { ctrl: true, name: 'u' });
Метод rl.write() записывает данные в readline Interface's input так, как если бы они были введены пользователем.
класс promises.Interface
Использование в Deno
import { promises } from "node:readline";
const { Interface } = promises;
Экземпляры класса readlinePromises.Interface создаются с помощью метода readlinePromises.createInterface(). Каждый экземпляр связан с одним потоком input Readable и одним потоком output Writable. Поток output используется для вывода приглашений к вводу данных пользователем, которые поступают из потока input и считываются из него.
Методы
question(query: string): Promise<string> Метод rl.question() отображает query, выводя его в поток output, ожидает ввода данных пользователем в input, а затем вызывает функцию callback, передавая введённые данные в качестве первого аргумента.
При вызове rl.question() возобновит поток input, если он был приостановлен.
Если Interface был создан с параметром output, установленным в значение null или undefined, query не выводится.
Если метод question вызывается после rl.close(), он возвращает отклонённый промис.
Пример использования:
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}`);
класс promises.Readline
Использование в Deno
import { promises } from "node:readline";
const { Readline } = promises;
Конструкторы
Readline(
stream: WritableStream,
options?: { autoCommit?: boolean; },
) Методы
Метод rl.clearLine() добавляет во внутренний список ожидающих действий действие, которое очищает текущую строку связанного stream в заданном направлении, определяемом dir. Вызовите rl.commit(), чтобы увидеть результат работы этого метода, если только конструктору не был передан параметр autoCommit: true.
clearScreenDown(): this Метод rl.clearScreenDown() добавляет во внутренний список ожидающих действий действие, которое очищает связанный поток от текущей позиции курсора вниз. Вызовите rl.commit(), чтобы увидеть результат работы этого метода, если только конструктору не был передан параметр autoCommit: true.
commit(): Promise<void> Метод rl.commit() отправляет все ожидающие действия в связанный stream и очищает внутренний список ожидающих действий.
cursorTo(
x: number,
y?: number,
): this Метод rl.cursorTo() добавляет во внутренний список ожидающих действий действие, которое перемещает курсор в указанную позицию связанного stream. Вызовите rl.commit(), чтобы увидеть результат работы этого метода, если только конструктору не был передан параметр autoCommit: true.
moveCursor(
dx: number,
dy: number,
): this Метод rl.moveCursor() добавляет во внутренний список ожидающих действий действие, которое перемещает курсор относительно его текущей позиции в связанном stream. Вызовите rl.commit(), чтобы увидеть результат работы этого метода, если только конструктору не был передан параметр autoCommit: true.
rollback(): this Метод rl.rollback очищает внутренний список ожидающих действий, не отправляя его в связанный stream.
функция clearLine
Использование в Deno
import { clearLine } from "node:readline";
clearLine(): booleanМетод readline.clearLine() очищает текущую строку заданного потока TTY в направлении, определяемом dir.
Параметры
stream: WritableStream dir: Direction callback: () => void Вызывается после завершения операции.
Возвращаемый тип
boolean false, если stream требуется, чтобы вызывающий код дождался генерации события 'drain', прежде чем продолжить запись дополнительных данных; в противном случае — true.
функция clearScreenDown
Использование в Deno
import { clearScreenDown } from "node:readline";
clearScreenDown(
stream: WritableStream,
callback?: () => void,
): booleanМетод readline.clearScreenDown() очищает указанный поток TTY от текущего положения курсора вниз.
Параметры
stream: WritableStream callback: () => void Вызывается после завершения операции.
Возвращаемый тип
boolean false, если stream требуется, чтобы вызывающий код дождался генерации события 'drain', прежде чем продолжить запись дополнительных данных; в противном случае true.
функция createInterface
Использование в Deno
import { createInterface } from "node:readline";
Перегрузка 1
createInterface(
input: ReadableStream,
output?: WritableStream,
completer?: Completer | AsyncCompleter,
terminal?: boolean,
): InterfaceМетод readline.createInterface() создает новый экземпляр readline.Interface.
import readline from '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 будет наиболее совместимым, если он определяет свойство output.columns и генерирует событие 'resize' для output при изменении числа столбцов (process.stdout делает это автоматически, если является TTY).
При создании readline.Interface с использованием stdin в качестве входных данных программа не завершится, пока не получит символ EOF. Чтобы выйти, не дожидаясь пользовательского ввода, вызовите process.stdin.unref().
Параметры
input: ReadableStream output: WritableStream completer: Completer | AsyncCompleter terminal: boolean Возвращаемый тип
Перегрузка 2
createInterface(options: ReadLineOptions): InterfaceПараметры
options: ReadLineOptions Возвращаемый тип
функция cursorTo
Использование в Deno
import { cursorTo } from "node:readline";
cursorTo(
stream: WritableStream,
x: number,
y?: number,
callback?: () => void,
): booleanМетод readline.cursorTo() перемещает курсор в указанное положение в заданном потоке TTY stream.
Параметры
stream: WritableStream x: number y: number callback: () => void Вызывается после завершения операции.
Возвращаемый тип
boolean false, если stream требуется, чтобы вызывающий код дождался генерации события 'drain', прежде чем продолжить запись дополнительных данных; в противном случае true.
функция emitKeypressEvents
Использование в Deno
import { emitKeypressEvents } from "node:readline";
emitKeypressEvents(
stream: ReadableStream,
readlineInterface?: Interface,
): voidМетод readline.emitKeypressEvents() заставляет указанный поток Readable начать генерировать события 'keypress', соответствующие полученным данным.
При необходимости interface задает экземпляр readline.Interface, для которого автодополнение отключается при обнаружении скопированных и вставленных данных.
Если stream является TTY, он должен находиться в режиме raw.
Этот метод автоматически вызывается любым экземпляром readline для его input, если input является терминалом. Закрытие экземпляра readline не останавливает генерацию событий 'keypress' потоком input.
readline.emitKeypressEvents(process.stdin);
if (process.stdin.isTTY)
process.stdin.setRawMode(true);
Пример: простая CLI
В следующем примере показано использование класса readline.Interface для реализации небольшого интерфейса командной строки:
import readline from '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);
});
Пример: чтение строк файлового потока
Распространенный сценарий использования readline — обработка входного файла построчно. Проще всего это сделать с помощью API fs.ReadStream и цикла for await...of:
import fs from 'node:fs';
import readline from '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':
import fs from 'node:fs';
import readline from '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, и скорость, можно применить смешанный подход:
import { once } from 'node:events';
import { createReadStream } from 'node:fs';
import { createInterface } from '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);
}
})();
Параметры
stream: ReadableStream readlineInterface: Interface Возвращаемый тип
void функция moveCursor
Использование в Deno
import { moveCursor } from "node:readline";
moveCursor(
stream: WritableStream,
dx: number,
dy: number,
callback?: () => void,
): booleanМетод readline.moveCursor() перемещает курсор относительно его текущего положения в заданном потоке TTY stream.
Параметры
stream: WritableStream dx: number dy: number callback: () => void Вызывается после завершения операции.
Возвращаемый тип
boolean false, если stream требуется, чтобы вызывающий код дождался генерации события 'drain', прежде чем продолжить запись дополнительных данных; в противном случае true.
функция promises.createInterface
Использование в Deno
import { promises } from "node:readline";
const { createInterface } = promises;
Перегрузка 1
createInterface(): InterfaceМетод readlinePromises.createInterface() создает новый экземпляр readlinePromises.Interface.
import readlinePromises from '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 будет наиболее совместимым, если он определяет свойство output.columns и генерирует событие 'resize' для output при изменении числа столбцов (process.stdout делает это автоматически, если является TTY).
Параметры
input: ReadableStream output: WritableStream completer: Completer terminal: boolean Возвращаемый тип
Перегрузка 2
createInterface(options: ReadLineOptions): InterfaceПараметры
options: ReadLineOptions Возвращаемый тип
интерфейс promises.ReadLineOptions
Использование в Deno
import { type promises } from "node:readline";
type { ReadLineOptions } = promises;
интерфейс ReadLineOptions
Использование в Deno
import { type ReadLineOptions } from "node:readline";
Свойства
output: WritableStream | undefined Поток Writable, в который записываются данные readline.
completer: Необязательная функция для автодополнения по клавише Tab.
terminal: boolean | undefined true, если потоки input и output следует считать терминалом TTY и записывать в него управляющие последовательности ANSI/VT100. По умолчанию при создании проверяется isTTY потока output.
history: string[] | undefined Начальный список строк истории. Этот параметр имеет смысл, только если пользователь или внутренняя проверка output установили для terminal значение true; в противном случае механизм кэширования истории вообще не инициализируется.
historySize: number | undefined Максимальное количество сохраняемых строк истории. Чтобы отключить историю, задайте этому значению 0. Этот параметр имеет смысл, только если пользователь или внутренняя проверка output установили для terminal значение true; в противном случае механизм кэширования истории вообще не инициализируется.
removeHistoryDuplicates: boolean | undefined Если true, при добавлении в список истории новой строки ввода, дублирующей более старую строку, старая строка удаляется из списка.
prompt: string | undefined Используемая строка приглашения.
crlfDelay: number | undefined Если задержка между \r и \n превышает crlfDelay миллисекунд, \r и \n будут считаться отдельными символами конца строки во входных данных. Значение crlfDelay будет преобразовано в число не меньше 100. Можно задать значение Infinity — в этом случае \r, за которым следует \n, всегда будет считаться одним символом новой строки (это может быть удобно при чтении файлов с разделителем строк \r\n).
escapeCodeTimeout: number | undefined Время, в течение которого readline ожидает ввода символа (в миллисекундах при чтении неоднозначной последовательности клавиш, которая может как образовать полную последовательность клавиш на основе уже считанных данных, так и потребовать дополнительного ввода для завершения более длинной последовательности клавиш).
tabSize: number | undefined Количество пробелов, соответствующее одной табуляции (не менее 1).
signal: AbortSignal | undefined Позволяет закрыть интерфейс с помощью AbortSignal. При прерывании сигнала интерфейс вызовет close.
пространство имён promises
Использование в Deno
import { promises } from "node:readline";
Классы
Экземпляры класса readlinePromises.Interface создаются с помощью метода readlinePromises.createInterface(). Каждый экземпляр связан с одним потоком input Readable и одним потоком output Writable. Поток output используется для вывода приглашений на ввод данных пользователем, которые поступают из потока input и считываются из него.
Функции
Метод readlinePromises.createInterface() создаёт новый экземпляр readlinePromises.Interface.
Интерфейсы
Псевдонимы типов
псевдоним типа AsyncCompleter
Использование в Deno
import { type AsyncCompleter } from "node:readline";
Определение
(
line: string,
callback: (
err?: null | Error,
result?: CompleterResult,
) => void,
) => void псевдоним типа Completer
Использование в Deno
import { type Completer } from "node:readline";
Определение
(line: string) => CompleterResult псевдоним типа CompleterResult
Использование в Deno
import { type CompleterResult } from "node:readline";
Определение
[string[], string] псевдоним типа Direction
Использование в Deno
import { type Direction } from "node:readline";
Определение
-1
| 0
| 1
псевдоним типа promises.Completer
Использование в Deno
import { type promises } from "node:readline";
type { Completer } = promises;
Определение
(line: string) => CompleterResult | Promise<CompleterResult>
© 2018–2025 the Deno authors
Licensed under the MIT License.
https://docs.deno.com/api/node/readline