การรับค่า ในภาษา TypeScript

26 December 2021

TypeScript เป็นภาษาที่ไม่มีอินเตอร์เฟสสำหรับรับค่า แต่วิธีการรับค่าจะให้มาสภาพแว้ดล้อมการที่โปรแกรมทำงานอยูแทน เช่น Node.js หรือเว็บเบราว์เซอร์ และในบทนี้ เราจะพูดถึงการรับค่าในภาษา TypeScript โดยการใช้งาน API ที่ให้มาโดย Node.js นี่เป็นเนื้อหาในบทนี้

  • การรับค่าผ่าน Command line อาร์กิวเมนต์
  • การรับค่าจากคีย์บอร์ดบน Node.js
  • การรับค่าจาก Readable stream

การรับค่าผ่าน Command line อาร์กิวเมนต์

การรับค่าพิื้นฐานสำหรับการเขียนโปรแกรมแบบ CLI ก็คือการรับค่าผ่าน Command line อาร์กิวเมนต์โดยการส่งค่าเข้าไปในโปรแกรมในตอนที่รันโปรแกรมด้วยคำสั่ง node นี่เป็นโปรแกรมที่มีการรับค่าผ่านทาง Command line อาร์กิวเมนต์ในภาษา TypeScript

greet.ts
let guestName: string = process.argv[2];
console.log(`Hello ${guestName}!`);

ในตัวอย่างนี้ เป็นโปรแกรมอย่างง่ายสำหรับกล่าวคำทักทายชื่อที่ถูกส่งเข้ามายังโปรแกรมผ่าน Command line อาร์กิวเมนต์ โดยที่หลังจากที่คอมไพล์โปรแกรมด้วยคำสั่ง tsc เสร็จแล้ว เราสามารถรันมันด้วยคำสั่งของ Node.js ตามปกติ

node greet.js David

ในการรันโปรแกรมนี้เราได้ส่งค่า David เข้าไปยังโปรแกรมผ่านทาง Command line อาร์กิวเมนต์ นี่เป็นผลลัพธ์การทำงานของโปรแกรม

Hello David!

ส่วนการรับค่าที่ส่งเข้ามายังโปรแกรมนั้นจะสามารถทำได้โดยอ่านค่าจากออบเจ็ค process.argv ซึ่งเป็นอาเรย์ที่รวบรวมอาร์กิวเมนต์ทั้งหมดที่ส่งเข้ามาในตอนรันโปรแกรม ที่ประกอบไปด้วยค่าดังต่อไปนี้

  • process.argv[0]: เป็นที่อยู่ของ Process ของ Node.js ที่ใช้รันโปรแกรม
  • process.argv[1]: เป็นที่อยู่ของไฟล์โปรแกรมที่รันในขณะที่
  • process.argv[2]: เป็นค่าที่เราส่งเข้ามาเพื่อใช้งานในโปรแกรม ในกรณีนี้คือ David

หรือเราสามารถดูข้อมูลทั้งหมดในออบเจ็ค process.argv ยกตัวอย่างเช่น

console.log(process.argv);

นี่เป็นผลลัพธ์การทำงานของโปรแกรม

[
  'C:\\Program Files\\nodejs\\node.exe',
  'C:\\marcuscode\\typescript\\myproject\\greet.js',
  'David'
]

นอกจากนี้ คุณยังสามารถส่งหลายค่าเข้าไปยังโปรแกรมได้โดยคั่นแต่ละค่าด้วยช่องว่าง ยกตัวอย่างเช่นในโปรแกรมนี้ เป็นโปรแกรมสำหรับกล่าวคำทักทายชื่อทั้งหมดที่ส่งเข้ามายังโปรแกรมผ่านทาง Command line อาร์กิวเมนต์

greeting_all.ts
let names: string[] = process.argv.slice(2);
names.forEach((name) => {
    console.log(`Hello ${name}!`);
});

จากนั้นคอมไพล์โปรแกรมและรันมันด้วยคำสั่ง

node greeting_all.js David John Charles

นี่เป็นผลลัพธ์การทำงานของโปรแกรม

Hello David!
Hello John!
Hello Charles!

ในตัวอย่างนี้ จะเห็นว่าเราได้ส่งสามรายชื่อเข้ามายังโปรแกรมผ่านทาง Command line และ Node.js จะอ่านค่าและรวบรวมมันไว้ในออบเจ็ค process.argv เช่นเดิม

let names: string[] = process.argv.slice(2);

เนื่องจากเราทราบว่าสองค่าแรกในอาเรย์เป็นที่อยู่ของ Process ของ Node.js และไฟล์ของโปรแกรมที่กำลังรัน ดังนั้นเราสามารถข้ามไปรับเอาชื่อทั้งหมดที่ส่งเข้ามาจากอาเรย์ Index ที่ 2 เป็นต้นไปโดยใช้เมธอด slice ของอาเรย์

ในการส่งค่าผ่าน Command line นั้น ค่าที่ได้รับจะเป็น String เสมอ ดังนั้นหากคุณต้องการใช้งานมันในเป็นตัวเลข คุณจะต้องแปลงค่าที่ได้รับให้เป็นตัวเลขด้วยตัวเอง นี่เป็นตัวอย่างของโปรแกรมหาผลรวมของตัวเลขที่ส่งเข้ามายังโปรแกรม

sum.ts
// Arguments received always be string
let values: string[] = process.argv.slice(2);

// Convert array of string to number
let numbers: number[] = values.map(n => Number(n));

// Find summation of numbers
let sum: number = 0;
numbers.forEach((n) => {
    sum += n;
});

console.log(`Sum = ${sum}`);

จากนั้นคอมไพล์และรันมันพร้อมกับส่งสามตัวเลขเข้าไปยังโปรแกรม

node sum.js 3 4 5

นี่เป็นผลลัพธ์การทำงานของโปรแกรม

Sum = 12

ในตัวอย่างนี้ เป็นโปรแกรมสำหรับหาผลรวมของตัวเลขที่ส่งเข้ามายังโปรแกรมผ่านทาง Command line อาร์กิวเมนต์ เราได้รวบรวมค่าทั้งหมดมาเก็บไว้ในอาเรย์ values จากนั้นใช้เมธอด map ของอาเรย์เพื่อวนแปลงค่าในอาเรย์ให้เป็นตัวเลขด้วยฟังก์ชัน Number

ในการรับค่าผ่าน Command line อาร์กิวเมนต์จะเห็นว่าค่าจะถูกส่งในตอนที่รันโปรแกรมเท่านั้น นี่มักจะใช้สำหรับกำหนดค่าเริ่มต้นให้กับโปรแกรมเพื่อทำงาน สำหรับการรับค่าอีกรูปแบบคือการรับค่าในขณะที่โปรแกรมกำลังทำงานอยู่

การรับค่าจากคีย์บอร์ดบน Node.js

โดยปกติแล้วการรับค่าในขณะที่โปรแกรมทำงานมักจะเป็นจากทางคีย์บอร์ด โดยเราสามารถอ่านค่านำเข้าได้จากออบเจ็ค process.stdin ซึ่งเป็นออบเจ็ค Readable stream ของ Node.js ที่จะเชื่อมต่อกับอุปกรณ์สำหรับรับค่าอย่างคีย์บอร์ด

ในตัวอย่างนี้ เป็นโปรแกรมรับชื่อจากทางคีย์บอร์ดและกล่าวทำทักทายชื่อที่รับมาออกทางหน้าจอ เช่นเดียวกับในตัวอย่างก่อนหน้า แต่การรับค่านี้จะเกิดขึ้นในขณะที่โปรแกรมกำลังทำงานอยู่แทน ซึ่งนี่เป็นรูปแบบการรับค่าที่พบได้ในโปรแกรมทั่วไป

greet_v2.ts
const readline = require('readline');

const readInterface = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

readInterface.question("What's your name? ", (name: string) => {
    console.log(`Hi ${name}!`);
    readInterface.close();
});

นี่เป็นผลลัพธ์การทำงานของโปรแกรม

What's your name? James
Hi James!

ในตัวอย่างนี้ โปรแกรมจะถามให้กรอกชื่อเข้ามาผ่านทางคีย์บอร์ดและกด Enter เพื่อจบการรับค่า หลังจากนั้นฟังก์ชัน Callback ที่กำหนดให้กับเมธอดจะทำงานพร้อมกับได้รับค่าที่รับมาได้ และโปรแกรมได้แสดงชื่อที่กรอกเข้ามา James ออกทางหน้าจอ

ในการรับค่าจากทางคีย์บอร์ด เราได้ใช้โมดูล readline ซึ่งเป็นโมดูลมาตฐานของ Node.js สำหรับรับค่าจากจากทางคีย์บอร์ดทีละบรรทัดที่ถูกส่งผ่านมาทาง Readable stream

const readInterface = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

ในคำสั่งนี้เป็นการสร้างออบเจ็ค readInterface ซึ่งเป็นการกำหนดช่องทางสำหรับการรับค่า โดยสำหรับช่องทางการรับค่าเราได้เชื่อมมันเข้ากับออบเจ็ค process.stdin ซึ่งก็คือคีย์บอร์ด และช่องทางการแสดงผล process.stdout ซึ่งก็คือ Console หรือจอภาพ

readInterface.question("What's your name? ", name => {
    console.log(`Hi ${name}!`);
    readInterface.close();
});

ในการรับค่าจะใช้เมธอด question บนออบเจ็คที่ได้สร้างไปก่อนหน้า โดยพารามิเตอร์แรกเป็นคำถามที่จะถามก่อนการรับค่า พารามิเตอร์ที่สองเป็นฟังก์ชัน Callback ที่จะทำงานเมื่อการรับค่าเสร็จสิ้น โดยฟังก์ชันจะได้รับค่ามาผ่านพารามิเตอร์ name

readInterface.close();

หลังจากการรับค่าเสร็จสิ้น เราจำเป็นต้องปิดการทำงานช่องทางการรับค่าและการแสดงผลที่ถูกสร้างขึ้นก่อนหน้าโดยเรียกใช้เมธอด close บนออบเจ็ค

การรับค่าจาก Readable stream

นอกจากการใช้งานโมดูล readline แล้ว เรายังสามารถอ่านค่าจาก Readable stream ผ่านทางออบเจ็ค process.stdin ได้โดยตรง นี่จะทำให้เราสามารถควบคุมวิธีการอ่านข้อมูลด้วยตัวเองได้ ในตัวอย่างนี้ เป็นโปรแกรมรับค่าจากทางคีย์บอร์ดและแสดงออกทางหน้าจอเช่นเดิม

input_stream.ts
console.log("Type something then press Enter");

const readable = process.stdin;
let buffer: string = "";

readable.on("readable", () => {
    let chunk: Buffer;
    while (null !== (chunk = readable.read())) {
        console.log(`Reading ${chunk.length} bytes of data...`);
        buffer += chunk;
    }
    console.log("Reached the end of stream");
    console.log("No more data to read");
    readable.emit("end");
});

readable.on("end", () => {
    console.log("Received:", buffer.toString());
});

นี่เป็นผลลัพธ์การทำงานของโปรแกรม

Type something then press Enter
I love TypeScript.
Reading 20 bytes of data...
Reached the end of stream
No more data to read
Received: I love TypeScript.

ในตัวอย่าง โปรแกรมจะถามให้กรอกชื่อผ่านทางคีย์บอร์ดและกด Enter เพื่อสิ้นสุดการรับค่า จะเห็นว่าการทำงานของโปรแกรมในตัวอย่างนี้จะคล้ายกับในตัวอย่างก่อนหน้า แต่ในตอนนี้เราจะควบคุมการรับค่าด้วยตัวเองจาก Readable stream ของ Node.js

while (null !== (chunk = readable.read())) {
    console.log(`Reading ${chunk.length} bytes of data...`);
    buffer += chunk;
}

ในการรับค่าจาก Steam สามารถใช้ Event readable เพื่อตรวจสอบเมื่อมีข้อมูลที่สามารถอ่านได้ใน Steam จากนั้นใช้งานเมธอด read เพื่ออ่านค่าจาก Stream ที่จะส่งข้อมูลกลับเป็น Buffer และเราใช้คำสั่ง while loop วนอ่านจนกว่าค่าที่ได้รับจะเป็น null ซึ่งนั่นหมายความว่าการรับค่าสิ้นสุด

เมื่อได้รับข้อมูลแล้ว เราสามารถเรียกใช้เมธอด emit สำหรับส่ง Event end เพื่อส่งสัญญาณว่าการรับค่าสิ้นสุดแล้ว และเพื่อนำข้อมูลที่รับมาได้ไปใช้ในโปรแกรมต่อไป

readable.on("end", () => {
    console.log("Received:", buffer.toString());
});

จากนั้นฟังก์ชัน Callback ที่ถูกกำหนดสำหรับ Event end จะทำงาน ในตอนนี้ เรานำค่าที่ได้รับทั้งหมดจากตัวแปร buffer มาแสดงผลออกทางหน้าจอ และโปรแกรมจบการทำงาน

ในบทนี้ คุณได้เรียนรู้เกี่ยวกับการรับค่าในภาษา TypeScript เราได้พูดถึงการรับค่าผ่านทาง Command line อาร์กิวเมนต์ และการรับค่าผ่านทางคีย์บอร์ดโดยใช้ API มาตรฐานของ Node.js และการรับค่าจาก Readable steam โดยตรง

บทความนี้เป็นประโยชน์หรือไม่? Yes · No