Skip to content

قراءة السطر

[مستقر: 2 - مستقر]

مستقر: 2 ثبات: 2 - مستقر

المصدر: lib/readline.js

يوفر مُعامل node:readline واجهة لقراءة البيانات من دفق قابل للقراءة (مثل process.stdin) سطرًا واحدًا في كل مرة.

لاستخدام واجهات برمجة التطبيقات القائمة على الوعود:

js
import * as readline from 'node:readline/promises'
js
const readline = require('node:readline/promises')

لاستخدام واجهات برمجة التطبيقات المتزامنة وواجهات برمجة التطبيقات القائمة على المُنعطفات:

js
import * as readline from 'node:readline'
js
const readline = require('node:readline')

يوضح المثال البسيط التالي الاستخدام الأساسي لمعامل node:readline.

js
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()
js
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: تسجيل الإجابة في قاعدة بيانات
  console.log(`Thank you for your valuable feedback: ${answer}`)

  rl.close()
})

بمجرد استدعاء هذا الرمز، لن ينتهي تطبيق Node.js حتى يتم إغلاق readline.Interface لأن الواجهة تنتظر استلام البيانات على دفق input.

فئة: InterfaceConstructor

مضاف في: v0.1.104

يتم إنشاء مثيلات فئة InterfaceConstructor باستخدام طريقة readlinePromises.createInterface() أو readline.createInterface(). يرتبط كل مثال بدفق إدخال واحد input قابل للقراءة ودفق إخراج واحد output قابل للكتابة. يتم استخدام دفق output لطباعة المطالبات لإدخال المستخدم الذي يصل إلى دفق input ويتم قراءته منه.

حدث: 'close'

مضاف في: v0.1.98

يُصدر حدث 'close' عندما يحدث أحد الأمور التالية:

  • يتم استدعاء طريقة rl.close() ويكون مثيل InterfaceConstructor قد تخلى عن التحكم في تدفقات الإدخال input والإخراج output؛
  • تتلقى دفق الإدخال input حدث 'end' الخاص به؛
  • تتلقى دفق الإدخال input + للإشارة إلى نهاية الإرسال (EOT)؛
  • تتلقى دفق الإدخال input + للإشارة إلى SIGINT ولا يوجد مستمع لحدث 'SIGINT' مسجل على مثيل InterfaceConstructor.

يتم استدعاء دالة المستمع بدون تمرير أي وسيطات.

يُكتمل مثيل InterfaceConstructor بمجرد إصدار حدث 'close'.

حدث: 'line'

مضاف في: v0.1.98

يُصدر حدث 'line' كلما تلقى دفق الإدخال input إدخال نهاية السطر (\n، \r، أو \r\n). يحدث هذا عادةً عندما يضغط المستخدم أو .

كما يتم إصدار حدث 'line' إذا تم قراءة بيانات جديدة من دفق وينتهي هذا الدفق بدون علامة نهاية سطر نهائية.

يتم استدعاء دالة المستمع مع سلسلة تحتوي على سطر واحد من الإدخال المستقبَل.

js
rl.on('line', input => {
  console.log(`Received: ${input}`)
})

حدث: 'history'

مضاف في: v15.8.0، v14.18.0

يُصدر حدث 'history' كلما تغيرت مصفوفة السجل.

يتم استدعاء دالة المستمع مع مصفوفة تحتوي على مصفوفة السجل. ستُعكس جميع التغييرات، الأسطر المضافة والأسطر المُزالة بسبب historySize و removeHistoryDuplicates.

الهدف الأساسي هو السماح للمستمع بالاحتفاظ بالسجل. من الممكن أيضًا أن يغيّر المستمع كائن السجل. قد يكون هذا مفيدًا لمنع إضافة أسطر معينة إلى السجل، مثل كلمة المرور.

js
rl.on('history', history => {
  console.log(`Received: ${history}`)
})

حدث: 'pause'

مضاف في: v0.7.5

يُصدر حدث 'pause' عندما يحدث أحد الأمور التالية:

  • يتم إيقاف دفق الإدخال input.
  • لا يتم إيقاف دفق الإدخال input ويتلقى حدث 'SIGCONT'. (انظر الأحداث 'SIGTSTP' و 'SIGCONT'.)

يتم استدعاء دالة المستمع بدون تمرير أي وسيطات.

js
rl.on('pause', () => {
  console.log('Readline paused.')
})

حدث: 'resume'

تم الإضافة في: v0.7.5

يتم إرسال حدث 'resume' كلما تم استئناف دفق input.

يتم استدعاء دالة المُستمع بدون تمرير أي وسيطات.

js
rl.on('resume', () => {
  console.log('Readline resumed.')
})

حدث: 'SIGCONT'

تم الإضافة في: v0.7.5

يتم إرسال حدث 'SIGCONT' عندما يتم إرجاع عملية Node.js التي تم نقلها مسبقًا إلى الخلفية باستخدام + (أي SIGTSTP) إلى المقدمة باستخدام fg(1p).

إذا تم إيقاف دفق input قبل طلب SIGTSTP، فلن يتم إرسال هذا الحدث.

يتم استدعاء دالة المُستمع بدون تمرير أي وسيطات.

js
rl.on('SIGCONT', () => {
  // `prompt` سيُعيد استئناف الدفق تلقائيًا
  rl.prompt()
})

حدث 'SIGCONT' غير مدعوم على Windows.

حدث: 'SIGINT'

تم الإضافة في: v0.3.0

يتم إرسال حدث 'SIGINT' كلما تلقى دفق input إدخالًا، يُعرف عادةً باسم SIGINT. إذا لم تكن هناك مُستمعات لحدث 'SIGINT' مسجلة عندما يتلقى دفق input إشارة SIGINT، فسيتم إرسال حدث 'pause'.

يتم استدعاء دالة المُستمع بدون تمرير أي وسيطات.

js
rl.on('SIGINT', () => {
  rl.question('Are you sure you want to exit? ', answer => {
    if (answer.match(/^y(es)?$/i)) rl.pause()
  })
})

حدث: 'SIGTSTP'

تم الإضافة في: v0.7.5

يتم إرسال حدث 'SIGTSTP' عندما يتلقى دفق input إدخالًا +، يُعرف عادةً باسم SIGTSTP. إذا لم تكن هناك مُستمعات لحدث 'SIGTSTP' مسجلة عندما يتلقى دفق input إشارة SIGTSTP، فسيتم إرسال عملية Node.js إلى الخلفية.

عندما يتم استئناف البرنامج باستخدام fg(1p)، سيتم إرسال حدثي 'pause' و 'SIGCONT'. ويمكن استخدام هذين الحدثين لاستئناف دفق input.

لن يتم إرسال حدثي 'pause' و 'SIGCONT' إذا تم إيقاف input قبل إرسال العملية إلى الخلفية.

يتم استدعاء دالة المُستمع بدون تمرير أي وسيطات.

js
rl.on('SIGTSTP', () => {
  // هذا سيُلغي SIGTSTP ويمنع البرنامج من الانتقال إلى الخلفية.
  console.log('Caught SIGTSTP.')
})

حدث 'SIGTSTP' غير مدعوم على Windows.

rl.close()

مضاف في: v0.1.98

تقوم طريقة rl.close() بإغلاق مثيل InterfaceConstructor والتخلي عن التحكم في تدفقات الإدخال (input) والإخراج (output). عند استدعائها، سيتم إصدار حدث 'close'.

إن استدعاء rl.close() لا يوقف على الفور الأحداث الأخرى (بما في ذلك 'line') من أن يتم إصدارها بواسطة مثيل InterfaceConstructor.

rl.pause()

مضاف في: v0.3.4

تقوم طريقة rl.pause() بإيقاف تدفق الإدخال (input) مؤقتًا، مما يسمح باستئنافه لاحقًا إذا لزم الأمر.

إن استدعاء rl.pause() لا يوقف على الفور الأحداث الأخرى (بما في ذلك 'line') من أن يتم إصدارها بواسطة مثيل InterfaceConstructor.

rl.prompt([preserveCursor])

مضاف في: v0.1.98

  • preserveCursor <boolean> إذا كانت true، تمنع إعادة تعيين موضع المؤشر إلى 0.

تقوم طريقة rl.prompt() بكتابة prompt المُهيأ لمثيلات InterfaceConstructor في سطر جديد في output لتزويد المستخدم بموقع جديد لتقديم الإدخال.

عند استدعائها، ستستأنف rl.prompt() تدفق الإدخال (input) إذا تم إيقافه مؤقتًا.

إذا تم إنشاء InterfaceConstructor مع تعيين output إلى null أو undefined، فلن يتم كتابة الموجه.

rl.resume()

مضاف في: v0.3.4

تقوم طريقة rl.resume() باستئناف تدفق الإدخال (input) إذا تم إيقافه مؤقتًا.

rl.setPrompt(prompt)

مضاف في: v0.1.98

تقوم طريقة rl.setPrompt() بتعيين الموجه الذي سيتم كتابته إلى output كلما تم استدعاء rl.prompt().

rl.getPrompt()

مضاف في: v15.3.0، v14.17.0

  • المُرجَع: <string> سلسلة الموجه الحالية

تقوم طريقة rl.getPrompt() بإرجاع الموجه الحالي الذي تستخدمه rl.prompt().

rl.write(data[, key])

مضاف في: v0.1.98

تقوم طريقة rl.write() بكتابة data أو تسلسل مفاتيح مُحدد بواسطة key إلى output. يتم دعم وسيطة key فقط إذا كان output عبارة عن وحدة طرفية نصية TTY. راجع ربطات مفاتيح TTY للحصول على قائمة بتركيبات المفاتيح.

إذا تم تحديد key، فسيتم تجاهل data.

عند استدعائها، ستستأنف rl.write() تدفق الإدخال (input) إذا تم إيقافه مؤقتًا.

إذا تم إنشاء InterfaceConstructor مع تعيين output إلى null أو undefined، فلن يتم كتابة data و key.

js
rl.write('Delete this!')
// محاكاة Ctrl+U لحذف السطر المكتوب سابقًا
rl.write(null, { ctrl: true, name: 'u' })

ستقوم طريقة rl.write() بكتابة البيانات إلى إدخال readline Interface كما لو تم تقديمها من قبل المستخدم.

rl[Symbol.asyncIterator]()

[History]

الإصدارالتغييرات
v11.14.0, v10.17.0لم يعد دعم Symbol.asyncIterator تجريبيًا.
v11.4.0, v10.16.0تمت الإضافة في: v11.4.0, v10.16.0

إنشاء كائن AsyncIterator الذي يتكرر عبر كل سطر في دفق الإدخال كسلسلة. تسمح هذه الطريقة بالتكرار غير المتزامن لأشياء InterfaceConstructor من خلال حلقات for await...of.

لا يتم إعادة توجيه الأخطاء في دفق الإدخال.

إذا تم إنهاء الحلقة باستخدام break أو throw أو return، فسيتم استدعاء rl.close(). بعبارة أخرى، فإن التكرار فوق InterfaceConstructor سيستهلك دائمًا دفق الإدخال بالكامل.

الأداء ليس على قدم المساواة مع واجهة برمجة التطبيقات التقليدية لحدث 'line'. استخدم 'line' بدلاً من ذلك للتطبيقات الحساسة للأداء.

js
async function processLineByLine() {
  const rl = readline.createInterface({
    // ...
  })

  for await (const line of rl) {
    // كل سطر في إدخال readline سيكون متاحًا تباعًا هنا كـ
    // `line`.
  }
}

سيبدأ readline.createInterface() في استهلاك دفق الإدخال بمجرد استدعائه. قد يؤدي وجود عمليات غير متزامنة بين إنشاء الواجهة والتكرار غير المتزامن إلى فقدان الأسطر.

rl.line

[History]

الإصدارالتغييرات
v15.8.0, v14.18.0ستكون القيمة دائمًا سلسلة، وليس غير معرفة.
v0.1.98تمت الإضافة في: v0.1.98

بيانات الإدخال الحالية التي تتم معالجتها بواسطة العقدة.

يمكن استخدام هذا عند جمع الإدخال من دفق TTY لاسترداد القيمة الحالية التي تم معالجتها حتى الآن، قبل إصدار حدث line. بمجرد إصدار حدث line، ستكون هذه الخاصية سلسلة فارغة.

كن على دراية بأن تعديل القيمة أثناء وقت تشغيل مثيل قد يكون له عواقب غير مقصودة إذا لم يتم التحكم في rl.cursor أيضًا.

إذا لم يتم استخدام دفق TTY للإدخال، فاستخدم حدث 'line'.

إحدى حالات الاستخدام الممكنة ستكون كما يلي:

js
const values = ['lorem ipsum', 'dolor sit amet']
const rl = readline.createInterface(process.stdin)
const showResults = debounce(() => {
  console.log('\n', values.filter(val => val.startsWith(rl.line)).join(' '))
}, 300)
process.stdin.on('keypress', (c, k) => {
  showResults()
})

rl.cursor

مضاف في: v0.1.98

موضع المؤشر بالنسبة إلى rl.line.

سيتعقب هذا المكان الذي يهبط فيه المؤشر الحالي في سلسلة الإدخال، عند قراءة الإدخال من دفق TTY. يحدد موضع المؤشر جزء سلسلة الإدخال الذي سيتم تعديله أثناء معالجة الإدخال، بالإضافة إلى العمود الذي سيتم عرض مؤشر المحطة الطرفية فيه.

rl.getCursorPos()

مضاف في: v13.5.0، v12.16.0

  • يعيد: <Object>
    • rows <number> صف المطالبة الذي يهبط عليه المؤشر حاليًا
    • cols <number> عمود الشاشة الذي يهبط عليه المؤشر حاليًا

يعيد الموضع الحقيقي للمؤشر بالنسبة إلى مطالبة الإدخال + السلسلة. يتم تضمين سلاسل الإدخال الطويلة (التفاف) بالإضافة إلى مطالبات متعددة الأسطر في الحسابات.

واجهة برمجة التطبيقات للوعود

مضاف في: v17.0.0

[مستقر: 1 - تجريبي]

مستقر: 1 استقرار: 1 - تجريبي

الفئة: readlinePromises.Interface

مضاف في: v17.0.0

يتم إنشاء مثيلات من فئة readlinePromises.Interface باستخدام طريقة readlinePromises.createInterface(). يرتبط كل مثال بدفق input قابل للقراءة واحد وبدفق output قابل للكتابة واحد. يتم استخدام دفق output لطباعة مطالبات إدخال المستخدم التي تصل إلى دفق input، ويتم قراءتها منه.

rl.question(query[, options])

مضاف في: v17.0.0

  • query <string> عبارة أو استعلام لكتابته إلى output، تُضاف قبل المطالَب.

  • options <Object>

    • signal <AbortSignal> يسمح بشكل اختياري بإلغاء question() باستخدام AbortSignal.
  • قيمة الإرجاع: <Promise> وعد يتم الوفاء به بإدخال المستخدم استجابةً لـ query.

تعرض طريقة rl.question() query بكتابتها إلى output، وتنتظر إدخال المستخدم على input، ثم تقوم باستدعاء دالة callback بإعطاء الإدخال المُقدم كأول وسيطة.

عند النداء، ستستأنف rl.question() تدفق input إذا تم إيقافه مؤقتًا.

إذا تم إنشاء readlinePromises.Interface مع تعيين output إلى null أو undefined، فلن يتم كتابة query.

إذا تم استدعاء السؤال بعد rl.close()، فإنه يُرجع وعدًا مرفوضًا.

مثال على الاستخدام:

js
const answer = await rl.question('ما هو طعامك المفضل؟ ')
console.log(`أوه، إذن طعامك المفضل هو ${answer}`)

استخدام AbortSignal لإلغاء سؤال.

js
const signal = AbortSignal.timeout(10_000)

signal.addEventListener(
  'abort',
  () => {
    console.log('انتهى وقت سؤال الطعام')
  },
  { once: true }
)

const answer = await rl.question('ما هو طعامك المفضل؟ ', { signal })
console.log(`أوه، إذن طعامك المفضل هو ${answer}`)

Class: readlinePromises.Readline

مضاف في: v17.0.0

new readlinePromises.Readline(stream[, options])

مضاف في: v17.0.0

rl.clearLine(dir)

مضاف في: v17.0.0

  • dir <عدد صحيح>

    • -1: إلى اليسار من المؤشر
    • 1: إلى اليمين من المؤشر
    • 0: السطر بأكمله
  • قيمة الإرجاع: this

تضيف طريقة rl.clearLine() إلى القائمة الداخلية للإجراءات المعلقة إجراءً يمسح السطر الحالي للـ stream المرتبط في اتجاه محدد يتم تحديده بواسطة dir. اتصل بـ rl.commit() لرؤية تأثير هذه الطريقة، ما لم يتم تمرير autoCommit: true إلى المُنشئ.

rl.clearScreenDown()

مضاف في: v17.0.0

  • قيمة الإرجاع: this

تضيف طريقة rl.clearScreenDown() إلى القائمة الداخلية للإجراءات المعلقة إجراءً يمسح stream المرتبط من الموضع الحالي للمؤشر إلى الأسفل. اتصل بـ rl.commit() لرؤية تأثير هذه الطريقة، ما لم يتم تمرير autoCommit: true إلى المُنشئ.

rl.commit()

مضاف في: v17.0.0

ترسل طريقة rl.commit() جميع الإجراءات المعلقة إلى stream المرتبط وتُمسح القائمة الداخلية للإجراءات المعلقة.

rl.cursorTo(x[, y])

مضاف في: v17.0.0

تضيف طريقة rl.cursorTo() إلى القائمة الداخلية للإجراءات المعلقة إجراءً ينقل المؤشر إلى الموضع المحدد في stream المرتبط. اتصل بـ rl.commit() لرؤية تأثير هذه الطريقة، ما لم يتم تمرير autoCommit: true إلى المُنشئ.

rl.moveCursor(dx, dy)

مضاف في: v17.0.0

تضيف طريقة rl.moveCursor() إلى القائمة الداخلية للإجراءات المعلقة إجراءً ينقل المؤشر بشكل نسبي إلى موضعه الحالي في stream المرتبط. اتصل بـ rl.commit() لرؤية تأثير هذه الطريقة، ما لم يتم تمرير autoCommit: true إلى المُنشئ.

rl.rollback()

مضاف في: v17.0.0

  • قيمة الإرجاع: this

تقوم طرق rl.rollback بمسح القائمة الداخلية من الإجراءات المعلقة بدون إرسالها إلى stream المرتبط.

readlinePromises.createInterface(options)

مضاف في: v17.0.0

  • options <Object>

    • input <stream.Readable> تدفق قابل للقراءة للاستماع إليه. هذا الخيار مطلوب.
    • output <stream.Writable> تدفق قابل للكتابة لكتابة بيانات readline إليه.
    • completer <Function> دالة اختيارية تُستخدم لإكمال علامات التبويب تلقائيًا.
    • terminal <boolean> true إذا كان يجب التعامل مع تدفقات input و output مثل TTY، وكتابة أكواد ANSI/VT100 المُهربة إليها. الافتراضي: التحقق من isTTY على تدفق output عند إنشاء مثيل.
    • history <string[]> القائمة الأولية لسطور التاريخ. هذا الخيار منطقي فقط إذا تم تعيين terminal على true من قبل المستخدم أو عن طريق فحص داخلي لـ output، وإلا فلن يتم تهيئة آلية تخزين التاريخ على الإطلاق. الافتراضي: [].
    • historySize <number> الحد الأقصى لعدد سطور التاريخ المُحتفظ بها. لإلغاء تمكين التاريخ، عيّن هذه القيمة على 0. هذا الخيار منطقي فقط إذا تم تعيين terminal على true من قبل المستخدم أو عن طريق فحص داخلي لـ output، وإلا فلن يتم تهيئة آلية تخزين التاريخ على الإطلاق. الافتراضي: 30.
    • removeHistoryDuplicates <boolean> إذا كان true، عندما يُضاف سطر إدخال جديد إلى قائمة التاريخ يُكرر سطرًا أقدم، فهذا سيُزيل السطر الأقدم من القائمة. الافتراضي: false.
    • prompt <string> سلسلة المطالبة التي سيتم استخدامها. الافتراضي: '\> '.
    • crlfDelay <number> إذا تجاوز التأخير بين \r و \n crlfDelay ميلي ثانية، فسيتم التعامل مع كل من \r و \n كمدخل منفصل لنهاية السطر. سيتم إجبار crlfDelay على رقم لا يقل عن 100. يمكن تعيينه على Infinity، وفي هذه الحالة سيتم دائمًا اعتبار \r متبوعًا بـ \n فاصل سطر واحد (وهو ما قد يكون معقولاً لـ قراءة الملفات باستخدام فاصل سطر \r\n). الافتراضي: 100.
    • escapeCodeTimeout <number> المدة التي سينتظرها readlinePromises حرفًا (عند قراءة تسلسل مفتاح غامض بالميلي ثانية، وهو ما يمكن أن يشكل كل من تسلسل مفتاح كامل باستخدام الإدخال الذي تم قراءته حتى الآن ويمكنه أخذ إدخال إضافي لإكمال تسلسل مفتاح أطول). الافتراضي: 500.
    • tabSize <integer> عدد المسافات التي تساوي علامة التبويب (الحد الأدنى 1). الافتراضي: 8.
  • قيمة الإرجاع: <readlinePromises.Interface>

تقوم طريقة readlinePromises.createInterface() بإنشاء مثيل جديد من readlinePromises.Interface.

js
import { createInterface } from 'node:readline/promises'
import { stdin, stdout } from 'node:process'
const rl = createInterface({
  input: stdin,
  output: stdout,
})
js
const { createInterface } = require('node:readline/promises')
const rl = createInterface({
  input: process.stdin,
  output: process.stdout,
})

بمجرد إنشاء مثيل readlinePromises.Interface، تكون الحالة الأكثر شيوعًا هي الاستماع إلى حدث 'line' :

js
rl.on('line', line => {
  console.log(`Received: ${line}`)
})

إذا كانت قيمة terminal هي true لهذا المثيل، فسيكون لتدفق output أفضل توافق إذا عرّف خاصية output.columns وأصدر حدث 'resize' على output إذا أو عندما تتغير الأعمدة (process.stdout يفعل هذا تلقائيًا عندما يكون TTY).

استخدام دالة completer

تأخذ دالة completer السطر الحالي الذي أدخله المستخدم كوسيط، وتعيد مصفوفة تحتوي على مُدخلين:

  • مصفوفة تحتوي على مُدخِلات مُطابقة للإكمال.
  • السلسلة الفرعية التي تم استخدامها للمطابقة.

على سبيل المثال: [[substr1, substr2, ...], originalsubstring].

js
function completer(line) {
  const completions = '.help .error .exit .quit .q'.split(' ')
  const hits = completions.filter(c => c.startsWith(line))
  // عرض جميع عمليات الإكمال إذا لم يتم العثور على أي شيء
  return [hits.length ? hits : completions, line]
}

يمكن لدالة completer أيضًا إعادة <Promise>، أو أن تكون غير متزامنة:

js
async function completer(linePartial) {
  await someAsyncWork()
  return [['123'], linePartial]
}

واجهة برمجة التطبيقات للاستدعاء العكسي

تمت الإضافة في: v0.1.104

الفئة: readline.Interface

[السجل]

الإصدارالتغييرات
v17.0.0الآن ترث الفئة readline.Interface من Interface.
v0.1.104تمت الإضافة في: v0.1.104

يتم إنشاء مثيلات فئة readline.Interface باستخدام طريقة readline.createInterface(). كل مثيل مرتبط بتيار إدخال input واحد قابل للقراءة وتيار إخراج output واحد قابل للكتابة. يتم استخدام تيار output لطباعة مطالبات إدخال المستخدم التي تصل إلى تيار input، ويتم قراءتها منه.

rl.question(query[, options], callback)

تمت الإضافة في: v0.3.3

  • query <string> عبارة أو استعلام لكتابته إلى output، يتم وضعه قبل المطالبة.

  • options <Object>

    • signal <AbortSignal> يسمح بشكل اختياري بإلغاء question() باستخدام AbortController.
  • callback <Function> دالة استدعاء عكسي يتم استدعاؤها مع إدخال المستخدم استجابةً لـ query.

تُعرض طريقة rl.question() الاستعلام query من خلال كتابته إلى output، وتنتظر إدخال المستخدم الذي سيتم توفيره على input، ثم تستدعي دالة callback وتمرر الإدخال المُقدم كوسيط أول.

عند استدعائها، ستستأنف rl.question() تيار input إذا تم إيقافه مؤقتًا.

إذا تم إنشاء readline.Interface مع تعيين output إلى null أو undefined، فلن يتم كتابة query.

لا تتبع دالة callback المُمررة إلى rl.question() النمط النموذجي المتمثل في قبول كائن Error أو null كوسيط أول. يتم استدعاء callback مع الإجابة المُقدمة كوسيط وحيد.

سيتم إرسال خطأ إذا تم استدعاء rl.question() بعد rl.close().

مثال على الاستخدام:

js
rl.question('What is your favorite food? ', answer => {
  console.log(`Oh, so your favorite food is ${answer}`)
})

باستخدام AbortController لإلغاء سؤال.

js
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])

[History]

الإصدارالتغييرات
v18.0.0يُلقي تمرير مُستدعي غير صالح إلى وسيطة callback الآن ERR_INVALID_ARG_TYPE بدلاً من ERR_INVALID_CALLBACK.
v12.7.0يتم الكشف عن مُستدعي و قيمة الإرجاع لـ write() للدفق.
v0.7.7تمت الإضافة في: v0.7.7
  • stream <stream.Writable>

  • dir <number>

    • -1: إلى اليسار من المؤشر
    • 1: إلى اليمين من المؤشر
    • 0: السطر بأكمله
  • callback <Function> يتم استدعاؤه بمجرد اكتمال العملية.

  • القيمة المُرجعه: <boolean> false إذا كان stream يرغب في أن تنتظر شفرة الاستدعاء حتى يتم إصدار حدث 'drain' قبل متابعة كتابة بيانات إضافية؛ خلاف ذلك true.

طريقة readline.clearLine() تقوم بمسح السطر الحالي من دفق TTY المُعطى في الاتجاه المحدد بواسطة dir.

readline.clearScreenDown(stream[, callback])

[History]

الإصدارالتغييرات
v18.0.0يُلقي تمرير مُستدعي غير صالح إلى وسيطة callback الآن ERR_INVALID_ARG_TYPE بدلاً من ERR_INVALID_CALLBACK.
v12.7.0يتم الكشف عن مُستدعي و قيمة الإرجاع لـ write() للدفق.
v0.7.7تمت الإضافة في: v0.7.7
  • stream <stream.Writable>
  • callback <Function> يتم استدعاؤه بمجرد اكتمال العملية.
  • القيمة المُرجعه: <boolean> false إذا كان stream يرغب في أن تنتظر شفرة الاستدعاء حتى يتم إصدار حدث 'drain' قبل متابعة كتابة بيانات إضافية؛ خلاف ذلك true.

طريقة readline.clearScreenDown() تقوم بمسح دفق TTY المُعطى من الموضع الحالي للمؤشر إلى الأسفل.

readline.createInterface(options)

[السجل]

الإصدارالتغييرات
v15.14.0، v14.18.0أصبح خيار signal مدعومًا الآن.
v15.8.0، v14.18.0أصبح خيار history مدعومًا الآن.
v13.9.0أصبح خيار tabSize مدعومًا الآن.
v8.3.0، v6.11.4إزالة الحد الأقصى لخيار crlfDelay.
v6.6.0أصبح خيار crlfDelay مدعومًا الآن.
v6.3.0أصبح خيار prompt مدعومًا الآن.
v6.0.0يمكن أن يكون خيار historySize مساويًا لـ 0 الآن.
v0.1.98تمت الإضافة في: v0.1.98
  • options <Object>

    • input <stream.Readable> تدفق قابل للقراءة للاستماع إليه. هذا الخيار مطلوب.
    • output <stream.Writable> تدفق قابل للكتابة لكتابة بيانات readline إليه.
    • completer <Function> دالة اختيارية تُستخدم لإكمال علامات التبويب تلقائيًا.
    • terminal <boolean> true إذا كان يجب التعامل مع تيارات input و output مثل TTY، وكتابة رموز الإفلات ANSI/VT100 إليها. الافتراضي: التحقق من isTTY على دفق output عند إنشاء مثيل.
    • history <string[]> القائمة الأولية لسطور التاريخ. يكون هذا الخيار منطقيًا فقط إذا تم تعيين terminal على true بواسطة المستخدم أو بواسطة فحص داخلي لـ output، وإلا فلن يتم تهيئة آلية تخزين التاريخ على الإطلاق. الافتراضي: [].
    • historySize <number> الحد الأقصى لعدد أسطر التاريخ التي يتم الاحتفاظ بها. لإلغاء تمكين التاريخ، عيّن هذه القيمة على 0. يكون هذا الخيار منطقيًا فقط إذا تم تعيين terminal على true بواسطة المستخدم أو بواسطة فحص داخلي لـ output، وإلا فلن يتم تهيئة آلية تخزين التاريخ على الإطلاق. الافتراضي: 30.
    • removeHistoryDuplicates <boolean> إذا كان true، فعندما يتم إضافة سطر إدخال جديد إلى قائمة التاريخ يكرر سطرًا أقدم، فسيتم إزالة السطر الأقدم من القائمة. الافتراضي: false.
    • prompt <string> سلسلة المطالبة التي سيتم استخدامها. الافتراضي: '\> '.
    • crlfDelay <number> إذا تجاوز التأخير بين \r و \n crlfDelay ميلي ثانية، فسيتم التعامل مع كل من \r و \n كمدخل منفصل لنهاية السطر. سيتم إجبار crlfDelay على رقم لا يقل عن 100. يمكن تعيينه على Infinity، وفي هذه الحالة سيتم اعتبار \r متبوعًا بـ \n دائمًا فاصل سطر واحد (وهو أمر معقول لـ قراءة الملفات باستخدام فاصل سطر \r\n). الافتراضي: 100.
    • escapeCodeTimeout <number> المدة التي ينتظرها readline حرفًا (عند قراءة تسلسل مفتاح غامض بالميلي ثانية، وهو ما يمكن أن يشكل تسلسل مفتاح كامل باستخدام الإدخال المقروء حتى الآن ويمكنه أخذ إدخال إضافي لإكمال تسلسل مفتاح أطول). الافتراضي: 500.
    • tabSize <integer> عدد المسافات التي تساوي علامة التبويب (الحد الأدنى 1). الافتراضي: 8.
    • signal <AbortSignal> يسمح بإغلاق الواجهة باستخدام AbortSignal. سيؤدي إلغاء الإشارة داخليًا إلى استدعاء close على الواجهة.
  • الإرجاع: <readline.Interface>

إن طريقة readline.createInterface() تُنشئ مثيلًا جديدًا لـ readline.Interface.

js
import { createInterface } from 'node:readline'
import { stdin, stdout } from 'node:process'
const rl = createInterface({
  input: stdin,
  output: stdout,
})
js
const { createInterface } = require('node:readline')
const rl = createInterface({
  input: process.stdin,
  output: process.stdout,
})

بمجرد إنشاء مثيل readline.Interface، فإن الحالة الأكثر شيوعًا هي الاستماع إلى حدث 'line':

js
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().

استخدام دالة completer

تأخذ دالة completer السطر الحالي الذي أدخله المستخدم كوسيطة، وتعيد Array يحتوي على مُدخلين:

  • Array يحتوي على المُدخَلات المُطابقة للإكمال.
  • السلسلة الفرعية التي تم استخدامها للمطابقة.

على سبيل المثال: [[substr1, substr2, ...], originalsubstring].

js
function completer(line) {
  const completions = '.help .error .exit .quit .q'.split(' ')
  const hits = completions.filter(c => c.startsWith(line))
  // عرض جميع عمليات الإكمال إذا لم يتم العثور على أي منها
  return [hits.length ? hits : completions, line]
}

يمكن استدعاء دالة completer بشكل غير متزامن إذا كانت تقبل وسيطتين:

js
function completer(linePartial, callback) {
  callback(null, [['123'], linePartial])
}

readline.cursorTo(stream, x[, y][, callback])

[History]

الإصدارالتغييرات
v18.0.0يؤدي تمرير مُنعطف غير صالح إلى وسيطة callback الآن إلى طرح ERR_INVALID_ARG_TYPE بدلاً من ERR_INVALID_CALLBACK.
v12.7.0تم الكشف عن مُنعطف و قيمة الإرجاع لـ write() للدفق.
v0.7.7تمت الإضافة في: v0.7.7
  • stream <stream.Writable>
  • x <number>
  • y <number>
  • callback <Function> يتم استدعاء هذه الدالة بمجرد اكتمال العملية.
  • القيمة المُرجعّة: <boolean> false إذا كان stream يرغب في أن ينتظر رمز الاستدعاء حدث 'drain' قبل المتابعة في كتابة بيانات إضافية؛ وإلا true.

تُنقل طريقة readline.cursorTo() المؤشر إلى الموضع المحدد في دفق TTY معين.

readline.moveCursor(stream, dx, dy[, callback])

[History]

الإصدارالتغييرات
v18.0.0يؤدي تمرير مُنعطف غير صالح إلى وسيطة callback الآن إلى طرح ERR_INVALID_ARG_TYPE بدلاً من ERR_INVALID_CALLBACK.
v12.7.0تم الكشف عن مُنعطف و قيمة الإرجاع لـ write() للدفق.
v0.7.7تمت الإضافة في: v0.7.7
  • stream <stream.Writable>
  • dx <number>
  • dy <number>
  • callback <Function> يتم استدعاء هذه الدالة بمجرد اكتمال العملية.
  • القيمة المُرجعّة: <boolean> false إذا كان stream يرغب في أن ينتظر رمز الاستدعاء حدث 'drain' قبل المتابعة في كتابة بيانات إضافية؛ وإلا true.

تُنقل طريقة readline.moveCursor() المؤشر بشكل نسبي إلى موضعه الحالي في دفق TTY معين.

readline.emitKeypressEvents(stream[, interface])

مضاف في: v0.7.7

تتسبب طريقة readline.emitKeypressEvents() في بدء تدفق قابل للقراءة المعطى في إصدار أحداث 'keypress' التي تتوافق مع الإدخال المستلم.

اختياريًا، يحدد interface مثيلًا لـ readline.Interface يتم تعطيل الإكمال التلقائي له عند الكشف عن إدخال تم نسخه ولصقه.

إذا كان stream عبارة عن TTY، فيجب أن يكون في الوضع الخام.

يتم استدعاء هذا تلقائيًا بواسطة أي مثيل readline على مُدخله input إذا كان input عبارة عن محطة طرفية. إن إغلاق مثيل readline لا يوقف input من إصدار أحداث 'keypress' .

js
readline.emitKeypressEvents(process.stdin)
if (process.stdin.isTTY) process.stdin.setRawMode(true)

مثال: واجهة سطر أوامر صغيرة

يوضح المثال التالي استخدام فئة readline.Interface لتنفيذ واجهة سطر أوامر صغيرة:

js
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)
})
js
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)
})

مثال: قراءة تدفق الملف سطرًا بسطر

حالة استخدام شائعة لـ readline هي استهلاك ملف إدخال سطرًا في كل مرة. أسهل طريقة للقيام بذلك هي الاستفادة من واجهة برمجة التطبيقات fs.ReadStream بالإضافة إلى حلقة for await...of:

js
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,
  })
  // ملاحظة: نستخدم خيار crlfDelay للتعرف على جميع حالات CR LF
  // ('\r\n') في input.txt كفاصل سطر واحد.

  for await (const line of rl) {
    // سيتوفر كل سطر في input.txt تباعًا هنا كـ `line`.
    console.log(`Line from file: ${line}`)
  }
}

processLineByLine()
js
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,
  })
  // ملاحظة: نستخدم خيار crlfDelay للتعرف على جميع حالات CR LF
  // ('\r\n') في input.txt كفاصل سطر واحد.

  for await (const line of rl) {
    // سيتوفر كل سطر في input.txt تباعًا هنا كـ `line`.
    console.log(`Line from file: ${line}`)
  }
}

processLineByLine()

بدلاً من ذلك، يمكن للمرء استخدام حدث 'line':

js
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(`Line from file: ${line}`)
})
js
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(`Line from file: ${line}`)
})

في الوقت الحالي، قد تكون حلقة for await...of أبطأ قليلاً. إذا كان تدفق async / await والسرعة كلاهما ضروريان، فيمكن تطبيق نهج مختلط:

js
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 => {
      // معالجة السطر.
    })

    await once(rl, 'close')

    console.log('File processed.')
  } catch (err) {
    console.error(err)
  }
})()
js
const { once } = require('node:events')
const { createReadStream } = require('node:fs')
const { createInterface } = require('node:readline')

;(async function processLineByLine() {
  try {
    const rl = createInterface({
      input: createReadStream('big-file.txt'),
      crlfDelay: Infinity,
    })

    rl.on('line', line => {
      // معالجة السطر.
    })

    await once(rl, 'close')

    console.log('File processed.')
  } catch (err) {
    console.error(err)
  }
})()

اختصارات لوحة المفاتيح لـTTY

اختصارات لوحة المفاتيحالوصفالملاحظات
+ +حذف السطر من اليسارلا يعمل على لينكس وماك ويندوز
+ +حذف السطر من اليمينلا يعمل على ماك
+إرسال SIGINT أو إغلاق مثيل readline
+حذف من اليسار
+حذف من اليمين أو إغلاق مثيل readline في حالة كان السطر الحالي فارغًا / EOFلا يعمل على ويندوز
+حذف من الموقع الحالي إلى بداية السطر
+حذف من الموقع الحالي إلى نهاية السطر
+نسخ (استدعاء) النص المحذوف سابقًايعمل فقط مع النص المحذوف بواسطة + أو +
+التنقل بين النصوص المحذوفة سابقًامتوفر فقط عندما يكون آخر ضغطة مفتاح + أو +
+الانتقال إلى بداية السطر
+الانتقال إلى نهاية السطر
+الرجوع حرفًا واحدًا
+التقدم حرفًا واحدًا
+مسح الشاشة
+عنصر التاريخ التالي
+عنصر التاريخ السابق
+التراجع عن التغيير السابقأي ضغطة مفتاح تُصدر رمز المفتاح 0x1F ستؤدي هذا الإجراء. في العديد من المحطات الطرفية، على سبيل المثال xterm ، يتم ربط هذا بـ + .
+إعادة التغيير السابقلا تحتوي العديد من المحطات الطرفية على اختصار لوحة مفاتيح لإعادة التنفيذ افتراضيًا. لقد اخترنا رمز المفتاح 0x1E لإجراء إعادة التنفيذ. في xterm ، يتم ربطه بـ + افتراضيًا.
+نقل العملية قيد التشغيل إلى الخلفية. اكتب fg واضغط على للرجوع.لا يعمل على ويندوز
+ أو +حذف للخلف إلى حدود الكلمة+ لا يعمل على لينكس وماك وويندوز
+حذف للأمام إلى حدود الكلمةلا يعمل على ماك
+ أو +كلمة يسار+ لا يعمل على ماك
+ أو +كلمة يمين+ لا يعمل على ماك
+ أو +حذف كلمة يمين+ لا يعمل على ويندوز
+حذف كلمة يسارلا يعمل على ماك