Menu

readline Node.js: Membaca Input User dari Terminal

Node.js tidak punya fungsi prompt(). Untuk mengajukan pertanyaan ke user di terminal, buat interface readline pada process.stdin lalu panggil question(), atau await dengan readline/promises.

Halaman ini dilengkapi editor yang bisa dijalankan. Edit, jalankan, dan lihat output-nya seketika.

Untuk membaca input user di Node.js, buat interface readline pada process.stdin dan bertanya dengan rl.question(). Node.js tidak punya prompt(): versi browser membuka dialog, dan program terminal tidak punya dialog. Bentuk modernnya memakai readline/promises, di mana await rl.question('Name? ') mengembalikan baris yang diketik user. Tutup interface-nya setelah selesai, atau program terus menunggu input berikutnya.

question() mencetak prompt-nya, menunggu satu baris input, lalu mengembalikannya tanpa newline, jadi programnya mencetak Next year you will be 37. Untuk beberapa pertanyaan, await satu question() setelah yang lain.

question() dari readline dengan callback

API aslinya, yang ada di setiap versi Node.js, memberikan jawaban ke sebuah callback. Pertanyaan bertingkat berarti callback bertingkat:

Program mencetak prompt-nya, lalu You picked blue. Jawabannya adalah string biasa, jadi trim dulu sebelum membandingkan: user yang mengetik spasi setelah kata itu akan mendapat 'blue ', yang tidak sama dengan 'blue'.

Membaca input per baris

Untuk memproses setiap baris sampai input berakhir, ulangi interface-nya dengan for await. Begitulah cara program membaca daftar yang diketik user (diakhiri dengan Ctrl+D) atau file yang di-pipe ke dalamnya dengan node index.js < numbers.txt. Kode lama melakukan hal yang sama dengan event, rl.on('line', fn) untuk setiap baris dan rl.on('close', fn) di akhir; perulangan ini adalah pasangan event itu yang ditulis dari atas ke bawah:

Hasilnya 3 numbers, total 49, dan perulangannya berhenti sendiri saat input berakhir, jadi tidak perlu close(). Tambahkan baris input keempat, 1, dan hasilnya menjadi 4 numbers, total 50.

Membaca seluruh stdin sekaligus

Untuk input yang di-pipe dari program lain (cat data.txt | node index.js), membaca semuanya dalam satu panggilan lebih sederhana. File descriptor 0 adalah standard input. File yang disimpan di Windows bisa mengakhiri barisnya dengan \r\n, jadi split dengan /\r?\n/ kalau input bisa datang dari sana:

Program mencetak ketiga item dalam satu kolom. readFileSync(0) memblokir sampai input lengkap, yang tidak masalah untuk script yang membaca pipe dan untuk pengujian, tetapi salah untuk alat interaktif, karena user harus mengetik semuanya sebelum melihat prompt apa pun.

Mana yang dipakai

Keempatnya membaca standard input yang sama. Bedanya ada pada kapan kodemu mendapat teksnya: satu jawaban setiap kali, satu baris setiap kali, atau semuanya di akhir.

KebutuhanPakai
Mengajukan beberapa pertanyaan berurutanreadline/promises dengan await rl.question()
Mendukung versi Node.js sebelum 17readline dengan callback question()
Menangani setiap baris saat tibafor await (const line of rl)
Membaca seluruh pipe atau file dari stdinfs.readFileSync(0, 'utf8')
Nilai sudah diketahui sebelum program dimulaiprocess.argv

Kesalahan umum

Lupa rl.close(). Interface-nya membiarkan standard input tetap terbuka, jadi program tidak pernah berhenti setelah pertanyaan terakhir. Tutup setelah kamu mendapat semua jawaban.

Memakai jawaban sebagai angka. Seperti semua yang diketik di terminal, jawabannya adalah string. '36' + 1 bernilai '361'; ubah dulu dengan Number().

Mem-pipe beberapa jawaban ke beberapa pertanyaan. Saat input datang dari pipe, bukan dari keyboard, readline membaca semuanya sekaligus, dan baris yang tiba sebelum question()-nya diajukan akan terbuang. Untuk input dari pipe, pakai perulangan for await atau readFileSync(0).

Tidak menyertakan opsi output. Tanpa output: process.stdout, question() tidak pernah mencetak prompt-nya, dan user hanya menatap terminal kosong. Perulangan per baris tidak membutuhkannya, karena tidak mencetak apa pun.

Pertanyaan yang sering diajukan

Kenapa prompt tidak terdefinisi di Node.js?

prompt() adalah fungsi browser yang membuka dialog, dan Node.js tidak punya jendela untuk membukanya. Pakai readline di Node.js, atau package seperti prompts atau inquirer untuk menu dan kolom password.

Bagaimana cara membaca password tanpa menampilkannya?

readline menampilkan setiap tombol yang ditekan. Package seperti prompts atau @inquirer/password menyamarkan inputnya; kalau mau melakukannya sendiri, kamu harus mengubah terminal ke raw mode dengan process.stdin.setRawMode(true) dan menangani setiap tombol.

Sebaiknya pakai readline atau process.argv?

Pakai process.argv saat nilainya sudah diketahui sebelum program dimulai, supaya program bisa berjalan di script tanpa ada orang yang menunggui. Pakai readline untuk alat interaktif yang mengajukan pertanyaan satu demi satu.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai