Readline
[Stabil: 2 - Stabil]
Stabil: 2 Stabilität: 2 - Stabil
Quellcode: lib/readline.js
Das node:readline
-Modul bietet eine Schnittstelle zum zeilenweisen Lesen von Daten aus einem Readable-Stream (wie z. B. process.stdin
).
Um die Promise-basierten APIs zu verwenden:
import * as readline from 'node:readline/promises';
const readline = require('node:readline/promises');
Um die Callback- und Sync-APIs zu verwenden:
import * as readline from 'node:readline';
const readline = require('node:readline');
Das folgende einfache Beispiel veranschaulicht die grundlegende Verwendung des node:readline
-Moduls.
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('Was halten Sie von Node.js? ');
console.log(`Vielen Dank für Ihr wertvolles 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('Was halten Sie von Node.js? ', (answer) => {
// TODO: Die Antwort in einer Datenbank protokollieren
console.log(`Vielen Dank für Ihr wertvolles Feedback: ${answer}`);
rl.close();
});
Sobald dieser Code aufgerufen wird, wird die Node.js-Anwendung erst beendet, wenn die readline.Interface
geschlossen wird, da die Schnittstelle darauf wartet, dass Daten im input
-Stream empfangen werden.
Klasse: InterfaceConstructor
Hinzugefügt in: v0.1.104
- Erweitert: <EventEmitter>
Instanzen der Klasse InterfaceConstructor
werden mit der Methode readlinePromises.createInterface()
oder readline.createInterface()
erstellt. Jede Instanz ist mit einem einzelnen input
Readable-Stream und einem einzelnen output
Writable-Stream verbunden. Der output
-Stream wird verwendet, um Eingabeaufforderungen für Benutzereingaben auszugeben, die im input
-Stream eingehen und aus diesem gelesen werden.
Event: 'close'
Hinzugefügt in: v0.1.98
Das 'close'
-Event wird ausgelöst, wenn eine der folgenden Bedingungen eintritt:
- Die Methode
rl.close()
wird aufgerufen und dieInterfaceConstructor
-Instanz hat die Kontrolle über dieinput
- undoutput
-Streams abgegeben; - Der
input
-Stream empfängt sein'end'
-Event; - Der
input
-Stream empfängt +, um das Ende der Übertragung (EOT) zu signalisieren; - Der
input
-Stream empfängt +, umSIGINT
zu signalisieren, und es ist kein'SIGINT'
-Event-Listener auf derInterfaceConstructor
-Instanz registriert.
Die Listener-Funktion wird aufgerufen, ohne Argumente zu übergeben.
Die InterfaceConstructor
-Instanz ist beendet, sobald das 'close'
-Event ausgelöst wird.
Event: 'line'
Hinzugefügt in: v0.1.98
Das 'line'
-Event wird immer dann ausgelöst, wenn der input
-Stream eine Zeilenende-Eingabe empfängt (\n
, \r
oder \r\n
). Dies geschieht normalerweise, wenn der Benutzer oder drückt.
Das 'line'
-Event wird auch ausgelöst, wenn neue Daten aus einem Stream gelesen wurden und dieser Stream ohne eine endgültige Zeilenende-Markierung endet.
Die Listener-Funktion wird mit einer Zeichenkette aufgerufen, die die einzelne Zeile der empfangenen Eingabe enthält.
rl.on('line', (input) => {
console.log(`Received: ${input}`);
});
Event: 'history'
Hinzugefügt in: v15.8.0, v14.18.0
Das 'history'
-Event wird immer dann ausgelöst, wenn sich das History-Array geändert hat.
Die Listener-Funktion wird mit einem Array aufgerufen, das das History-Array enthält. Es spiegelt alle Änderungen wider, hinzugefügte Zeilen und entfernte Zeilen aufgrund von historySize
und removeHistoryDuplicates
.
Der Hauptzweck ist es, einem Listener zu ermöglichen, die History zu persistieren. Es ist auch möglich, dass der Listener das History-Objekt ändert. Dies könnte nützlich sein, um zu verhindern, dass bestimmte Zeilen wie ein Passwort zur History hinzugefügt werden.
rl.on('history', (history) => {
console.log(`Received: ${history}`);
});
Event: 'pause'
Hinzugefügt in: v0.7.5
Das 'pause'
-Event wird ausgelöst, wenn eine der folgenden Bedingungen eintritt:
- Der
input
-Stream wird pausiert. - Der
input
-Stream ist nicht pausiert und empfängt das'SIGCONT'
-Event. (Siehe Events'SIGTSTP'
und'SIGCONT'
.)
Die Listener-Funktion wird aufgerufen, ohne Argumente zu übergeben.
rl.on('pause', () => {
console.log('Readline paused.');
});
Ereignis: 'resume'
Hinzugefügt in: v0.7.5
Das 'resume'
-Ereignis wird ausgelöst, wenn der input
-Stream fortgesetzt wird.
Die Listener-Funktion wird ohne Übergabe von Argumenten aufgerufen.
rl.on('resume', () => {
console.log('Readline fortgesetzt.');
});
Ereignis: 'SIGCONT'
Hinzugefügt in: v0.7.5
Das 'SIGCONT'
-Ereignis wird ausgelöst, wenn ein Node.js-Prozess, der zuvor mit + (d. h. SIGTSTP
) in den Hintergrund verschoben wurde, dann mit fg(1p)
wieder in den Vordergrund gebracht wird.
Wenn der input
-Stream vor der SIGTSTP
-Anfrage pausiert wurde, wird dieses Ereignis nicht ausgelöst.
Die Listener-Funktion wird ohne Übergabe von Argumenten aufgerufen.
rl.on('SIGCONT', () => {
// `prompt` wird den Stream automatisch fortsetzen
rl.prompt();
});
Das 'SIGCONT'
-Ereignis wird unter Windows nicht unterstützt.
Ereignis: 'SIGINT'
Hinzugefügt in: v0.3.0
Das 'SIGINT'
-Ereignis wird ausgelöst, wenn der input
-Stream eine Eingabe empfängt, die typischerweise als SIGINT
bekannt ist. Wenn keine 'SIGINT'
-Ereignis-Listener registriert sind, wenn der input
-Stream ein SIGINT
empfängt, wird das 'pause'
-Ereignis ausgelöst.
Die Listener-Funktion wird ohne Übergabe von Argumenten aufgerufen.
rl.on('SIGINT', () => {
rl.question('Sind Sie sicher, dass Sie beenden möchten? ', (answer) => {
if (answer.match(/^y(es)?$/i)) rl.pause();
});
});
Ereignis: 'SIGTSTP'
Hinzugefügt in: v0.7.5
Das 'SIGTSTP'
-Ereignis wird ausgelöst, wenn der input
-Stream eine + Eingabe empfängt, die typischerweise als SIGTSTP
bekannt ist. Wenn keine 'SIGTSTP'
-Ereignis-Listener registriert sind, wenn der input
-Stream ein SIGTSTP
empfängt, wird der Node.js-Prozess in den Hintergrund geschickt.
Wenn das Programm mit fg(1p)
fortgesetzt wird, werden die 'pause'
- und 'SIGCONT'
-Ereignisse ausgelöst. Diese können verwendet werden, um den input
-Stream fortzusetzen.
Die 'pause'
- und 'SIGCONT'
-Ereignisse werden nicht ausgelöst, wenn der input
pausiert wurde, bevor der Prozess in den Hintergrund geschickt wurde.
Die Listener-Funktion wird ohne Übergabe von Argumenten aufgerufen.
rl.on('SIGTSTP', () => {
// Dies überschreibt SIGTSTP und verhindert, dass das Programm in den
// Hintergrund geht.
console.log('SIGTSTP abgefangen.');
});
Das 'SIGTSTP'
-Ereignis wird unter Windows nicht unterstützt.
rl.close()
Hinzugefügt in: v0.1.98
Die Methode rl.close()
schließt die InterfaceConstructor
-Instanz und gibt die Kontrolle über die input
- und output
-Streams ab. Beim Aufruf wird das 'close'
-Ereignis ausgelöst.
Der Aufruf von rl.close()
verhindert nicht sofort, dass andere Ereignisse (einschließlich 'line'
) von der InterfaceConstructor
-Instanz ausgelöst werden.
rl.pause()
Hinzugefügt in: v0.3.4
Die Methode rl.pause()
pausiert den input
-Stream und ermöglicht es, ihn später bei Bedarf fortzusetzen.
Der Aufruf von rl.pause()
pausiert nicht sofort andere Ereignisse (einschließlich 'line'
), die von der InterfaceConstructor
-Instanz ausgelöst werden.
rl.prompt([preserveCursor])
Hinzugefügt in: v0.1.98
preserveCursor
<boolean> Wenntrue
, verhindert, dass die Cursorposition auf0
zurückgesetzt wird.
Die Methode rl.prompt()
schreibt den konfigurierten prompt
der InterfaceConstructor
-Instanzen in eine neue Zeile in output
, um dem Benutzer eine neue Stelle zur Eingabe zu bieten.
Beim Aufruf setzt rl.prompt()
den input
-Stream fort, falls er pausiert wurde.
Wenn der InterfaceConstructor
mit output
auf null
oder undefined
gesetzt wurde, wird die Eingabeaufforderung nicht geschrieben.
rl.resume()
Hinzugefügt in: v0.3.4
Die Methode rl.resume()
setzt den input
-Stream fort, falls er pausiert wurde.
rl.setPrompt(prompt)
Hinzugefügt in: v0.1.98
prompt
<string>
Die Methode rl.setPrompt()
legt die Eingabeaufforderung fest, die bei jedem Aufruf von rl.prompt()
in output
geschrieben wird.
rl.getPrompt()
Hinzugefügt in: v15.3.0, v14.17.0
- Gibt zurück: <string> die aktuelle Prompt-Zeichenkette
Die Methode rl.getPrompt()
gibt den aktuellen Prompt zurück, der von rl.prompt()
verwendet wird.
rl.write(data[, key])
Hinzugefügt in: v0.1.98
Die Methode rl.write()
schreibt entweder data
oder eine durch key
identifizierte Tastenfolge in die output
. Das key
-Argument wird nur unterstützt, wenn output
ein TTY-Textterminal ist. Siehe TTY-Tastenkombinationen für eine Liste von Tastenkombinationen.
Wenn key
angegeben ist, wird data
ignoriert.
Beim Aufruf setzt rl.write()
den input
-Stream fort, falls er pausiert wurde.
Wenn der InterfaceConstructor
mit output
auf null
oder undefined
gesetzt wurde, werden data
und key
nicht geschrieben.
rl.write('Delete this!');
// Simulate Ctrl+U to delete the line written previously
rl.write(null, { ctrl: true, name: 'u' });
Die Methode rl.write()
schreibt die Daten in den input
des readline
-Interface
, als ob sie vom Benutzer bereitgestellt würden.
rl[Symbol.asyncIterator]()
[Verlauf]
Version | Änderungen |
---|---|
v11.14.0, v10.17.0 | Die Unterstützung von Symbol.asyncIterator ist nicht mehr experimentell. |
v11.4.0, v10.16.0 | Hinzugefügt in: v11.4.0, v10.16.0 |
- Gibt zurück: <AsyncIterator>
Erstellt ein AsyncIterator
-Objekt, das jede Zeile im Eingabestream als Zeichenkette durchläuft. Diese Methode ermöglicht die asynchrone Iteration von InterfaceConstructor
-Objekten durch for await...of
-Schleifen.
Fehler im Eingabestream werden nicht weitergeleitet.
Wenn die Schleife mit break
, throw
oder return
beendet wird, wird rl.close()
aufgerufen. Mit anderen Worten, das Iterieren über einen InterfaceConstructor
verbraucht immer den Eingabestream vollständig.
Die Leistung ist nicht mit der traditionellen 'line'
-Event-API vergleichbar. Verwenden Sie stattdessen 'line'
für leistungssensible Anwendungen.
async function processLineByLine() {
const rl = readline.createInterface({
// ...
});
for await (const line of rl) {
// Jede Zeile in der Readline-Eingabe wird hier sukzessive als
// `line` verfügbar sein.
}
}
readline.createInterface()
beginnt mit dem Verarbeiten des Eingabestreams, sobald es aufgerufen wird. Asynchrone Operationen zwischen der Erstellung der Schnittstelle und der asynchronen Iteration können dazu führen, dass Zeilen verpasst werden.
rl.line
[Verlauf]
Version | Änderungen |
---|---|
v15.8.0, v14.18.0 | Der Wert ist immer eine Zeichenkette, niemals undefiniert. |
v0.1.98 | Hinzugefügt in: v0.1.98 |
Die aktuellen Eingabedaten, die von Node verarbeitet werden.
Dies kann verwendet werden, wenn die Eingabe von einem TTY-Stream erfasst wird, um den aktuellen Wert abzurufen, der bisher verarbeitet wurde, bevor das line
-Event ausgelöst wird. Sobald das line
-Event ausgelöst wurde, ist diese Eigenschaft eine leere Zeichenkette.
Beachten Sie, dass die Änderung des Werts während der Instanzlaufzeit unbeabsichtigte Folgen haben kann, wenn rl.cursor
nicht ebenfalls gesteuert wird.
Wenn Sie keinen TTY-Stream für die Eingabe verwenden, nutzen Sie das 'line'
-Event.
Ein möglicher Anwendungsfall wäre wie folgt:
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
Hinzugefügt in: v0.1.98
Die Cursorposition relativ zu rl.line
.
Dies verfolgt, wo der aktuelle Cursor in der Eingabezeichenkette landet, wenn die Eingabe von einem TTY-Stream gelesen wird. Die Cursorposition bestimmt den Teil der Eingabezeichenkette, der bei der Verarbeitung der Eingabe geändert wird, sowie die Spalte, in der die Terminalcaret gerendert wird.
rl.getCursorPos()
Hinzugefügt in: v13.5.0, v12.16.0
- Gibt zurück: <Object>
Gibt die tatsächliche Position des Cursors in Bezug auf die Eingabeaufforderung + Zeichenkette zurück. Lange Eingabezeichenketten (Umbruch) sowie mehrzeilige Eingabeaufforderungen sind in den Berechnungen enthalten.
Promises API
Hinzugefügt in: v17.0.0
[Stabil: 1 - Experimentell]
Stabil: 1 Stabilität: 1 - Experimentell
Klasse: readlinePromises.Interface
Hinzugefügt in: v17.0.0
- Erweitert: <readline.InterfaceConstructor>
Instanzen der Klasse readlinePromises.Interface
werden mit der Methode readlinePromises.createInterface()
erstellt. Jede Instanz ist einem einzelnen input
Readable-Stream und einem einzelnen output
Writable-Stream zugeordnet. Der output
-Stream wird verwendet, um Eingabeaufforderungen für Benutzereingaben auszugeben, die im input
-Stream eingehen und von ihm gelesen werden.
rl.question(query[, options])
Hinzugefügt in: v17.0.0
query
<string> Eine Anweisung oder Abfrage, die inoutput
geschrieben und dem Prompt vorangestellt wird.options
<Object>signal
<AbortSignal> Ermöglicht optional das Abbrechen vonquestion()
mithilfe einesAbortSignal
.
Gibt zurück: <Promise> Ein Promise, das mit der Benutzereingabe als Antwort auf die
query
erfüllt wird.
Die Methode rl.question()
zeigt die query
an, indem sie in output
geschrieben wird, wartet auf die Eingabe des Benutzers in input
und ruft dann die callback
-Funktion auf, wobei die bereitgestellte Eingabe als erstes Argument übergeben wird.
Beim Aufruf setzt rl.question()
den input
-Stream fort, falls er pausiert wurde.
Wenn readlinePromises.Interface
mit output
auf null
oder undefined
gesetzt wurde, wird die query
nicht geschrieben.
Wenn die Frage nach rl.close()
aufgerufen wird, wird ein abgewiesenes Promise zurückgegeben.
Beispiel für die Verwendung:
const answer = await rl.question('Was ist dein Lieblingsessen? ');
console.log(`Ach so, dein Lieblingsessen ist ${answer}`);
Verwenden eines AbortSignal
zum Abbrechen einer Frage.
const signal = AbortSignal.timeout(10_000);
signal.addEventListener('abort', () => {
console.log('Die Essensfrage hat das Zeitlimit überschritten');
}, { once: true });
const answer = await rl.question('Was ist dein Lieblingsessen? ', { signal });
console.log(`Ach so, dein Lieblingsessen ist ${answer}`);
Klasse: readlinePromises.Readline
Hinzugefügt in: v17.0.0
new readlinePromises.Readline(stream[, options])
Hinzugefügt in: v17.0.0
stream
<stream.Writable> Ein TTY-Stream.options
<Object>autoCommit
<boolean> Wenntrue
, mussrl.commit()
nicht aufgerufen werden.
rl.clearLine(dir)
Hinzugefügt in: v17.0.0
dir
<integer>-1
: Links vom Cursor1
: Rechts vom Cursor0
: Die gesamte Zeile
Gibt zurück: this
Die rl.clearLine()
Methode fügt der internen Liste ausstehender Aktionen eine Aktion hinzu, die die aktuelle Zeile des zugehörigen stream
in einer durch dir
angegebenen Richtung löscht. Rufen Sie rl.commit()
auf, um die Auswirkung dieser Methode zu sehen, es sei denn, autoCommit: true
wurde an den Konstruktor übergeben.
rl.clearScreenDown()
Hinzugefügt in: v17.0.0
- Gibt zurück: this
Die rl.clearScreenDown()
Methode fügt der internen Liste ausstehender Aktionen eine Aktion hinzu, die den zugehörigen Stream von der aktuellen Cursorposition abwärts löscht. Rufen Sie rl.commit()
auf, um die Auswirkung dieser Methode zu sehen, es sei denn, autoCommit: true
wurde an den Konstruktor übergeben.
rl.commit()
Hinzugefügt in: v17.0.0
- Gibt zurück: <Promise>
Die rl.commit()
Methode sendet alle ausstehenden Aktionen an den zugehörigen stream
und löscht die interne Liste ausstehender Aktionen.
rl.cursorTo(x[, y])
Hinzugefügt in: v17.0.0
Die rl.cursorTo()
Methode fügt der internen Liste ausstehender Aktionen eine Aktion hinzu, die den Cursor an die angegebene Position im zugehörigen stream
bewegt. Rufen Sie rl.commit()
auf, um die Auswirkung dieser Methode zu sehen, es sei denn, autoCommit: true
wurde an den Konstruktor übergeben.
rl.moveCursor(dx, dy)
Hinzugefügt in: v17.0.0
Die rl.moveCursor()
Methode fügt der internen Liste ausstehender Aktionen eine Aktion hinzu, die den Cursor relativ zu seiner aktuellen Position im zugehörigen stream
bewegt. Rufen Sie rl.commit()
auf, um die Auswirkung dieser Methode zu sehen, es sei denn, autoCommit: true
wurde an den Konstruktor übergeben.
rl.rollback()
Hinzugefügt in: v17.0.0
- Gibt zurück: this
Die rl.rollback
-Methode löscht die interne Liste der ausstehenden Aktionen, ohne sie an den zugehörigen stream
zu senden.
readlinePromises.createInterface(options)
Hinzugefügt in: v17.0.0
options
<Object>input
<stream.Readable> Der Readable-Stream, auf den gehört werden soll. Diese Option ist erforderlich.output
<stream.Writable> Der Writable-Stream, in den Readline-Daten geschrieben werden sollen.completer
<Function> Eine optionale Funktion, die für die automatische Tab-Vervollständigung verwendet wird.terminal
<boolean>true
, wenn dieinput
- undoutput
-Streams wie ein TTY behandelt werden sollen und ANSI/VT100-Escape-Codes in diese geschrieben werden sollen. Standard: Überprüfen vonisTTY
auf demoutput
-Stream bei der Instanziierung.history
<string[]> Initialisierungsliste der Verlaufszeilen. Diese Option ist nur sinnvoll, wennterminal
vom Benutzer oder durch eine interneoutput
-Prüfung auftrue
gesetzt wird, andernfalls wird der History-Caching-Mechanismus überhaupt nicht initialisiert. Standard:[]
.historySize
<number> Maximale Anzahl der beibehaltenen Verlaufszeilen. Um den Verlauf zu deaktivieren, setzen Sie diesen Wert auf0
. Diese Option ist nur sinnvoll, wennterminal
vom Benutzer oder durch eine interneoutput
-Prüfung auftrue
gesetzt wird, andernfalls wird der History-Caching-Mechanismus überhaupt nicht initialisiert. Standard:30
.removeHistoryDuplicates
<boolean> Wenntrue
, wird die ältere Zeile aus der Liste entfernt, wenn eine neue Eingabezeile, die der Verlaufsliste hinzugefügt wird, eine ältere Zeile dupliziert. Standard:false
.prompt
<string> Die zu verwendende Prompt-Zeichenkette. Standard:'\> '
.crlfDelay
<number> Wenn die Verzögerung zwischen\r
und\n
crlfDelay
-Millisekunden überschreitet, werden sowohl\r
als auch\n
als separate End-of-Line-Eingaben behandelt.crlfDelay
wird zu einer Zahl von nicht weniger als100
konvertiert. Sie kann aufInfinity
gesetzt werden, in diesem Fall wird\r
, gefolgt von\n
, immer als einzelner Zeilenumbruch betrachtet (was für das Lesen von Dateien mit\r\n
-Zeilentrennzeichen sinnvoll sein kann). Standard:100
.escapeCodeTimeout
<number> Die Dauer, diereadlinePromises
auf ein Zeichen wartet (beim Lesen einer mehrdeutigen Schlüsselsequenz in Millisekunden, die sowohl eine vollständige Schlüsselsequenz mit der bisher gelesenen Eingabe bilden als auch zusätzliche Eingaben zur Vervollständigung einer längeren Schlüsselsequenz entgegennehmen kann). Standard:500
.tabSize
<integer> Die Anzahl der Leerzeichen, die einem Tab entsprechen (Minimum 1). Standard:8
.
Gibt zurück: <readlinePromises.Interface>
Die readlinePromises.createInterface()
-Methode erstellt eine neue readlinePromises.Interface
-Instanz.
import { createInterface } from 'node:readline/promises';
import { stdin, stdout } from 'node:process';
const rl = createInterface({
input: stdin,
output: stdout,
});
const { createInterface } = require('node:readline/promises');
const rl = createInterface({
input: process.stdin,
output: process.stdout,
});
Sobald die readlinePromises.Interface
-Instanz erstellt wurde, ist es am häufigsten, auf das 'line'
-Ereignis zu hören:
rl.on('line', (line) => {
console.log(`Received: ${line}`);
});
Wenn terminal
für diese Instanz true
ist, erhält der output
-Stream die beste Kompatibilität, wenn er eine output.columns
-Eigenschaft definiert und ein 'resize'
-Ereignis auf dem output
auslöst, wenn oder wann sich die Spalten jemals ändern (process.stdout
tut dies automatisch, wenn es ein TTY ist).
Verwendung der Funktion completer
Die Funktion completer
nimmt die aktuelle, vom Benutzer eingegebene Zeile als Argument und gibt ein Array
mit 2 Einträgen zurück:
- Ein
Array
mit übereinstimmenden Einträgen für die Vervollständigung. - Die Teilzeichenfolge, die für die Übereinstimmung verwendet wurde.
Zum Beispiel: [[substr1, substr2, ...], originalsubstring]
.
function completer(line) {
const completions = '.help .error .exit .quit .q'.split(' ');
const hits = completions.filter((c) => c.startsWith(line));
// Alle Vervollständigungen anzeigen, wenn keine gefunden wurden
return [hits.length ? hits : completions, line];
}
Die Funktion completer
kann auch ein <Promise> zurückgeben oder asynchron sein:
async function completer(linePartial) {
await someAsyncWork();
return [['123'], linePartial];
}
Callback-API
Hinzugefügt in: v0.1.104
Klasse: readline.Interface
[Verlauf]
Version | Änderungen |
---|---|
v17.0.0 | Die Klasse readline.Interface erbt jetzt von Interface . |
v0.1.104 | Hinzugefügt in: v0.1.104 |
- Erweitert: <readline.InterfaceConstructor>
Instanzen der Klasse readline.Interface
werden mit der Methode readline.createInterface()
erstellt. Jede Instanz ist mit einem einzelnen input
-Readable-Stream und einem einzelnen output
-Writable-Stream verbunden. Der output
-Stream wird verwendet, um Eingabeaufforderungen für Benutzereingaben auszugeben, die auf dem input
-Stream eingehen und von diesem gelesen werden.
rl.question(query[, options], callback)
Hinzugefügt in: v0.3.3
query
<string> Eine Anweisung oder Abfrage, die inoutput
geschrieben wird und der Eingabeaufforderung vorangestellt wird.options
<Object>signal
<AbortSignal> Ermöglicht optional das Abbrechen vonquestion()
mithilfe einesAbortController
.
callback
<Function> Eine Callback-Funktion, die mit der Benutzereingabe als Antwort auf diequery
aufgerufen wird.
Die Methode rl.question()
zeigt die query
an, indem sie in die output
geschrieben wird, wartet auf die Eingabe des Benutzers in input
und ruft dann die callback
-Funktion auf, wobei die bereitgestellte Eingabe als erstes Argument übergeben wird.
Wenn rl.question()
aufgerufen wird, setzt es den input
-Stream fort, falls er pausiert wurde.
Wenn das readline.Interface
mit output
auf null
oder undefined
gesetzt wurde, wird die query
nicht geschrieben.
Die an rl.question()
übergebene callback
-Funktion folgt nicht dem typischen Muster, ein Error
-Objekt oder null
als erstes Argument zu akzeptieren. Die callback
wird mit der bereitgestellten Antwort als einzigem Argument aufgerufen.
Es wird ein Fehler ausgelöst, wenn rl.question()
nach rl.close()
aufgerufen wird.
Beispielhafte Verwendung:
rl.question('Was ist dein Lieblingsessen? ', (answer) => {
console.log(`Ach so, dein Lieblingsessen ist also ${answer}`);
});
Verwenden eines AbortController
zum Abbrechen einer Frage.
const ac = new AbortController();
const signal = ac.signal;
rl.question('Was ist dein Lieblingsessen? ', { signal }, (answer) => {
console.log(`Ach so, dein Lieblingsessen ist also ${answer}`);
});
signal.addEventListener('abort', () => {
console.log('Die Essensfrage hat das Zeitlimit überschritten');
}, { once: true });
setTimeout(() => ac.abort(), 10000);
readline.clearLine(stream, dir[, callback])
[Verlauf]
Version | Änderungen |
---|---|
v18.0.0 | Das Übergeben eines ungültigen Rückrufs an das Argument callback wirft jetzt ERR_INVALID_ARG_TYPE anstelle von ERR_INVALID_CALLBACK . |
v12.7.0 | Der Write()-Rückruf und der Rückgabewert des Streams werden verfügbar gemacht. |
v0.7.7 | Hinzugefügt in: v0.7.7 |
stream
<stream.Writable>dir
<number>-1
: links vom Cursor1
: rechts vom Cursor0
: die gesamte Zeile
callback
<Function> Wird aufgerufen, sobald der Vorgang abgeschlossen ist.Gibt zurück: <boolean>
false
, wennstream
möchte, dass der aufrufende Code wartet, bis das Ereignis'drain'
ausgelöst wurde, bevor er mit dem Schreiben zusätzlicher Daten fortfährt; andernfallstrue
.
Die Methode readline.clearLine()
löscht die aktuelle Zeile des gegebenen TTY-Streams in einer bestimmten Richtung, die durch dir
identifiziert wird.
readline.clearScreenDown(stream[, callback])
[Verlauf]
Version | Änderungen |
---|---|
v18.0.0 | Das Übergeben eines ungültigen Rückrufs an das Argument callback wirft jetzt ERR_INVALID_ARG_TYPE anstelle von ERR_INVALID_CALLBACK . |
v12.7.0 | Der Write()-Rückruf und der Rückgabewert des Streams werden verfügbar gemacht. |
v0.7.7 | Hinzugefügt in: v0.7.7 |
stream
<stream.Writable>callback
<Function> Wird aufgerufen, sobald der Vorgang abgeschlossen ist.- Gibt zurück: <boolean>
false
, wennstream
möchte, dass der aufrufende Code wartet, bis das Ereignis'drain'
ausgelöst wurde, bevor er mit dem Schreiben zusätzlicher Daten fortfährt; andernfallstrue
.
Die Methode readline.clearScreenDown()
löscht den gegebenen TTY-Stream von der aktuellen Position des Cursors nach unten.
readline.createInterface(options)
[Verlauf]
Version | Änderungen |
---|---|
v15.14.0, v14.18.0 | Die Option signal wird jetzt unterstützt. |
v15.8.0, v14.18.0 | Die Option history wird jetzt unterstützt. |
v13.9.0 | Die Option tabSize wird jetzt unterstützt. |
v8.3.0, v6.11.4 | Die maximale Beschränkung der Option crlfDelay wurde entfernt. |
v6.6.0 | Die Option crlfDelay wird jetzt unterstützt. |
v6.3.0 | Die Option prompt wird jetzt unterstützt. |
v6.0.0 | Die Option historySize kann jetzt 0 sein. |
v0.1.98 | Hinzugefügt in: v0.1.98 |
options
<Object>input
<stream.Readable> Der Readable-Stream, auf den gehört werden soll. Diese Option ist erforderlich.output
<stream.Writable> Der Writable-Stream, in den Readline-Daten geschrieben werden sollen.completer
<Function> Eine optionale Funktion, die für die automatische Tab-Vervollständigung verwendet wird.terminal
<boolean>true
, wenn dieinput
- undoutput
-Streams wie ein TTY behandelt werden sollen und ANSI/VT100-Escape-Codes in diese geschrieben werden sollen. Standard: Überprüfung vonisTTY
auf demoutput
-Stream bei der Instanziierung.history
<string[]> Anfängliche Liste von Verlaufseinträgen. Diese Option ist nur sinnvoll, wennterminal
vom Benutzer oder durch eine interneoutput
-Prüfung auftrue
gesetzt wird, andernfalls wird der Verlaufscaching-Mechanismus überhaupt nicht initialisiert. Standard:[]
.historySize
<number> Maximale Anzahl der beibehaltenen Verlaufseinträge. Um den Verlauf zu deaktivieren, setzen Sie diesen Wert auf0
. Diese Option ist nur sinnvoll, wennterminal
vom Benutzer oder durch eine interneoutput
-Prüfung auftrue
gesetzt wird, andernfalls wird der Verlaufscaching-Mechanismus überhaupt nicht initialisiert. Standard:30
.removeHistoryDuplicates
<boolean> Wenntrue
, und eine neue Eingabezeile, die der Verlaufsliste hinzugefügt wird, eine ältere Zeile dupliziert, wird diese ältere Zeile aus der Liste entfernt. Standard:false
.prompt
<string> Die zu verwendende Prompt-Zeichenkette. Standard:'\> '
.crlfDelay
<number> Wenn die Verzögerung zwischen\r
und\n
crlfDelay
Millisekunden überschreitet, werden sowohl\r
als auch\n
als separate End-of-Line-Eingaben behandelt.crlfDelay
wird zu einer Zahl von mindestens100
konvertiert. Es kann aufInfinity
gesetzt werden, in welchem Fall\r
, gefolgt von\n
, immer als einzelnes Newline-Zeichen betrachtet wird (was für das Lesen von Dateien mit\r\n
Zeilentrennzeichen sinnvoll sein kann). Standard:100
.escapeCodeTimeout
<number> Die Dauer, diereadline
auf ein Zeichen wartet (beim Lesen einer mehrdeutigen Tastenfolge in Millisekunden, die sowohl eine vollständige Tastenfolge mit der bisher gelesenen Eingabe bilden kann als auch zusätzliche Eingaben entgegennehmen kann, um eine längere Tastenfolge zu vervollständigen). Standard:500
.tabSize
<integer> Die Anzahl der Leerzeichen, die einem Tab entsprechen (mindestens 1). Standard:8
.signal
<AbortSignal> Ermöglicht das Schließen der Schnittstelle mithilfe eines AbortSignals. Das Abbrechen des Signals ruft internclose
auf der Schnittstelle auf.
Returns: <readline.Interface>
Die Methode readline.createInterface()
erstellt eine neue readline.Interface
-Instanz.
import { createInterface } from 'node:readline';
import { stdin, stdout } from 'node:process';
const rl = createInterface({
input: stdin,
output: stdout,
});
const { createInterface } = require('node:readline');
const rl = createInterface({
input: process.stdin,
output: process.stdout,
});
Sobald die readline.Interface
-Instanz erstellt wurde, ist es üblich, auf das 'line'
-Ereignis zu warten:
rl.on('line', (line) => {
console.log(`Empfangen: ${line}`);
});
Wenn terminal
für diese Instanz true
ist, erhält der output
-Stream die beste Kompatibilität, wenn er eine output.columns
-Eigenschaft definiert und ein 'resize'
-Ereignis auf dem output
ausgibt, wenn oder wann sich die Spalten jemals ändern (process.stdout
tut dies automatisch, wenn es ein TTY ist).
Beim Erstellen einer readline.Interface
mit stdin
als Eingabe wird das Programm erst beendet, wenn es ein EOF-Zeichen empfängt. Um zu beenden, ohne auf Benutzereingaben zu warten, rufen Sie process.stdin.unref()
auf.
Verwendung der Funktion completer
Die Funktion completer
nimmt die aktuelle vom Benutzer eingegebene Zeile als Argument entgegen und gibt ein Array
mit 2 Einträgen zurück:
- Ein
Array
mit übereinstimmenden Einträgen für die Vervollständigung. - Die Teilzeichenfolge, die für die Übereinstimmung verwendet wurde.
Zum Beispiel: [[substr1, substr2, ...], originalsubstring]
.
function completer(line) {
const completions = '.help .error .exit .quit .q'.split(' ');
const hits = completions.filter((c) => c.startsWith(line));
// Alle Vervollständigungen anzeigen, wenn keine gefunden wurden
return [hits.length ? hits : completions, line];
}
Die Funktion completer
kann asynchron aufgerufen werden, wenn sie zwei Argumente akzeptiert:
function completer(linePartial, callback) {
callback(null, [['123'], linePartial]);
}
readline.cursorTo(stream, x[, y][, callback])
[Verlauf]
Version | Änderungen |
---|---|
v18.0.0 | Die Übergabe eines ungültigen Rückrufs an das callback -Argument wirft jetzt ERR_INVALID_ARG_TYPE anstelle von ERR_INVALID_CALLBACK . |
v12.7.0 | Der write()-Rückruf und der Rückgabewert des Streams werden verfügbar gemacht. |
v0.7.7 | Hinzugefügt in: v0.7.7 |
stream
<stream.Writable>x
<number>y
<number>callback
<Funktion> Wird aufgerufen, sobald der Vorgang abgeschlossen ist.- Gibt zurück: <boolean>
false
, wennstream
wünscht, dass der aufrufende Code wartet, bis das'drain'
-Ereignis ausgelöst wird, bevor er mit dem Schreiben zusätzlicher Daten fortfährt; andernfallstrue
.
Die Methode readline.cursorTo()
bewegt den Cursor an die angegebene Position in einem gegebenen TTY-stream
.
readline.moveCursor(stream, dx, dy[, callback])
[Verlauf]
Version | Änderungen |
---|---|
v18.0.0 | Die Übergabe eines ungültigen Rückrufs an das callback -Argument wirft jetzt ERR_INVALID_ARG_TYPE anstelle von ERR_INVALID_CALLBACK . |
v12.7.0 | Der write()-Rückruf und der Rückgabewert des Streams werden verfügbar gemacht. |
v0.7.7 | Hinzugefügt in: v0.7.7 |
stream
<stream.Writable>dx
<number>dy
<number>callback
<Funktion> Wird aufgerufen, sobald der Vorgang abgeschlossen ist.- Gibt zurück: <boolean>
false
, wennstream
wünscht, dass der aufrufende Code wartet, bis das'drain'
-Ereignis ausgelöst wird, bevor er mit dem Schreiben zusätzlicher Daten fortfährt; andernfallstrue
.
Die Methode readline.moveCursor()
bewegt den Cursor relativ zu seiner aktuellen Position in einem gegebenen TTY-stream
.
readline.emitKeypressEvents(stream[, interface])
Hinzugefügt in: v0.7.7
stream
<stream.Readable>interface
<readline.InterfaceConstructor>
Die Methode readline.emitKeypressEvents()
bewirkt, dass der gegebene Readable-Stream beginnt, 'keypress'
-Ereignisse auszugeben, die der empfangenen Eingabe entsprechen.
Optional gibt interface
eine readline.Interface
-Instanz an, für die die automatische Vervollständigung deaktiviert wird, wenn Copy-Paste-Eingaben erkannt werden.
Wenn der stream
ein TTY ist, muss er sich im Raw-Modus befinden.
Dies wird automatisch von jeder Readline-Instanz auf ihrem input
aufgerufen, wenn der input
ein Terminal ist. Das Schließen der readline
-Instanz verhindert nicht, dass der input
'keypress'
-Ereignisse ausgibt.
readline.emitKeypressEvents(process.stdin);
if (process.stdin.isTTY)
process.stdin.setRawMode(true);
Beispiel: Winzige CLI
Das folgende Beispiel veranschaulicht die Verwendung der Klasse readline.Interface
zur Implementierung einer kleinen Befehlszeilenschnittstelle:
import { createInterface } from 'node:readline';
import { exit, stdin, stdout } from 'node:process';
const rl = createInterface({
input: stdin,
output: 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!');
exit(0);
});
const { createInterface } = require('node:readline');
const rl = 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);
});
Beispiel: Datei-Stream Zeile für Zeile lesen
Ein häufiger Anwendungsfall für readline
ist die zeilenweise Verarbeitung einer Eingabedatei. Der einfachste Weg, dies zu tun, ist die Verwendung der fs.ReadStream
API sowie einer for await...of
-Schleife:
import { createReadStream } from 'node:fs';
import { createInterface } from 'node:readline';
async function processLineByLine() {
const fileStream = createReadStream('input.txt');
const rl = createInterface({
input: fileStream,
crlfDelay: Infinity,
});
// Hinweis: Wir verwenden die Option crlfDelay, um alle Instanzen von CR LF
// ('\r\n') in input.txt als einzelnen Zeilenumbruch zu erkennen.
for await (const line of rl) {
// Jede Zeile in input.txt wird hier nacheinander als `line` verfügbar sein.
console.log(`Zeile aus Datei: ${line}`);
}
}
processLineByLine();
const { createReadStream } = require('node:fs');
const { createInterface } = require('node:readline');
async function processLineByLine() {
const fileStream = createReadStream('input.txt');
const rl = createInterface({
input: fileStream,
crlfDelay: Infinity,
});
// Hinweis: Wir verwenden die Option crlfDelay, um alle Instanzen von CR LF
// ('\r\n') in input.txt als einzelnen Zeilenumbruch zu erkennen.
for await (const line of rl) {
// Jede Zeile in input.txt wird hier nacheinander als `line` verfügbar sein.
console.log(`Zeile aus Datei: ${line}`);
}
}
processLineByLine();
Alternativ könnte man das 'line'
Event verwenden:
import { createReadStream } from 'node:fs';
import { createInterface } from 'node:readline';
const rl = createInterface({
input: createReadStream('sample.txt'),
crlfDelay: Infinity,
});
rl.on('line', (line) => {
console.log(`Zeile aus Datei: ${line}`);
});
const { createReadStream } = require('node:fs');
const { createInterface } = require('node:readline');
const rl = createInterface({
input: createReadStream('sample.txt'),
crlfDelay: Infinity,
});
rl.on('line', (line) => {
console.log(`Zeile aus Datei: ${line}`);
});
Aktuell kann die for await...of
-Schleife etwas langsamer sein. Wenn async
/ await
-Flow und Geschwindigkeit beide wichtig sind, kann ein gemischter Ansatz angewendet werden:
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);
}
})();
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-Tastenkombinationen
Tastenkombinationen | Beschreibung | Hinweise |
---|---|---|
+ + | Zeile links löschen | Funktioniert nicht unter Linux, Mac und Windows |
+ + | Zeile rechts löschen | Funktioniert nicht unter Mac |
+ | Sendet SIGINT oder schließt die Readline-Instanz | |
+ | Links löschen | |
+ | Rechts löschen oder die Readline-Instanz schließen, falls die aktuelle Zeile leer ist / EOF | Funktioniert nicht unter Windows |
+ | Löscht von der aktuellen Position zum Zeilenanfang | |
+ | Löscht von der aktuellen Position zum Zeilenende | |
+ | Einfügen (Abrufen) des zuvor gelöschten Textes | Funktioniert nur mit Text, der durch + oder + gelöscht wurde |
+ | Durchläuft zuvor gelöschte Texte | Nur verfügbar, wenn der letzte Tastendruck + oder + war |
+ | Gehe zum Zeilenanfang | |
+ | Gehe zum Zeilenende | |
+ | Ein Zeichen zurück | |
+ | Ein Zeichen vorwärts | |
+ | Bildschirm löschen | |
+ | Nächster Eintrag in der Historie | |
+ | Vorheriger Eintrag in der Historie | |
+ | Vorherige Änderung rückgängig machen | Jeder Tastendruck, der den Keycode 0x1F sendet, führt diese Aktion aus. In vielen Terminals, z. B. xterm , ist dies an + gebunden. |
+ | Vorherige Änderung wiederherstellen | Viele Terminals haben keinen standardmäßigen Wiederherstellungs-Tastendruck. Wir wählen den Keycode 0x1E , um die Wiederherstellung durchzuführen. In xterm ist es standardmäßig an + gebunden. |
+ | Verschiebt den laufenden Prozess in den Hintergrund. Tippen Sie fg und drücken Sie , um zurückzukehren. | Funktioniert nicht unter Windows |
+ oder + | Rückwärts bis zu einer Wortgrenze löschen | + Funktioniert nicht unter Linux, Mac und Windows |
+ | Vorwärts bis zu einer Wortgrenze löschen | Funktioniert nicht unter Mac |
+ oder + | Wort links | + Funktioniert nicht unter Mac |
+ oder + | Wort rechts | + Funktioniert nicht unter Mac |
+ oder + | Wort rechts löschen | + Funktioniert nicht unter Windows |
+ | Wort links löschen | Funktioniert nicht unter Mac |