ฟังก์ชัน Generator ใน JavaScript

ฟังก์ชัน Generator ใน JavaScript

ในบทความนี้ เราจะอธิบายฟังก์ชัน Generator ใน JavaScript

YouTube Video

ฟังก์ชัน Generator ใน JavaScript

ฟังก์ชัน Generator ใน JavaScript เป็นฟังก์ชันพิเศษที่แตกต่างจากฟังก์ชันทั่วไป เนื่องจากสามารถดำเนินการแบบ lazy execution และ หยุดชั่วคราวและดำเนินการต่อได้ การเข้าใจฟังก์ชัน Generator จะช่วยให้คุณสามารถจัดการกับการดำเนินงานแบบอะซิงโครนัสและการประมวลผลข้อมูลขนาดใหญ่ได้อย่างมีประสิทธิภาพ ในที่นี้ เราจะอธิบายรายละเอียดเกี่ยวกับวิธีการทำงานของฟังก์ชัน Generator วิธีการใช้งาน และกรณีการใช้จริง

ฟังก์ชัน Generator คืออะไร?

ฟังก์ชัน Generator ถูกกำหนดด้วย function* (คำจำกัดความของฟังก์ชันที่มีดอกจัน) และแตกต่างจากฟังก์ชันทั่วไป เนื่องจากสามารถหยุดชั่วคราวระหว่างการทำงานและดำเนินการต่อในขณะที่ยังรักษาสถานะเดิมไว้ได้ ฟังก์ชัน Generator ช่วยให้เกิด "lazy execution" และคืนค่าผลลัพธ์ทีละขั้นตอน ซึ่งช่วยให้การจัดการหน่วยความจำและการประมวลผลตามลำดับเป็นไปอย่างมีประสิทธิภาพ

ไวยากรณ์

1function* generatorFunction() {
2    yield 'First value';
3    yield 'Second value';
4    return 'Done';
5}

ในลักษณะนี้ ฟังก์ชัน Generator สามารถมีคำสั่ง yield หลายตัว และใช้ yield เพื่อหยุดการทำงานชั่วคราวได้ เมื่อฟังก์ชัน Generator ถูกเรียกใช้งาน เนื้อหาของฟังก์ชันจะไม่ถูกดำเนินการทันที และจะคืนค่า generator object คุณสามารถเรียกใช้เมธอด next() บนวัตถุนี้เพื่อดำเนินการฟังก์ชันต่อจากจุดที่หยุดไว้

การใช้งานพื้นฐานของฟังก์ชัน Generator

ถัดไป ลองดูตัวอย่างพื้นฐานของการใช้งานฟังก์ชัน Generator

 1function* simpleGenerator() {
 2    yield 1;
 3    yield 2;
 4    yield 3;
 5}
 6
 7const gen = simpleGenerator();
 8
 9console.log(gen.next()); // { value: 1, done: false }
10console.log(gen.next()); // { value: 2, done: false }
11console.log(gen.next()); // { value: 3, done: false }
12console.log(gen.next()); // { value: undefined, done: true }

จุดสำคัญที่ควรทราบคือ Generator จะคืนค่าด้วย yield ทุกครั้ง และตราบใดที่คุณสมบัติ done เป็น false หมายความว่ายังมีค่าที่จะถูกคืนมาอีก การเรียก next() ครั้งสุดท้ายจะคืนค่า done: true ซึ่งหมายถึง Generator ได้ทำงานเสร็จสมบูรณ์แล้ว

คีย์เวิร์ด yield และการหยุดชั่วคราวค่า

yield เป็นคีย์เวิร์ดที่ระบุจุดที่หยุดชั่วคราวภายในฟังก์ชัน Generator ค่าทางด้านขวาของ yield จะถูกคืนกลับเมื่อมีการเรียกใช้ next() นอกจากนี้ yield ยังรองรับการสื่อสารแบบสองทางอีกด้วย พูดอีกอย่างคือ เมื่อส่งค่าผ่านเป็นอาร์กิวเมนต์ไปยังเมธอด next() ค่านั้นจะถูกส่งไปยังฟังก์ชัน Generator

 1function* generatorWithYield() {
 2    const value1 = yield 'First yield';
 3    console.log('Received value:', value1);
 4    const value2 = yield 'Second yield';
 5    console.log('Received value:', value2);
 6}
 7
 8const gen = generatorWithYield();
 9
10console.log(gen.next());        // { value: 'First yield', done: false }
11console.log(gen.next('Apple')); // Received value: Apple
12                                // { value: 'Second yield', done: false }
13console.log(gen.next('Banana'));// Received value: Banana
14                                // { value: undefined, done: true }

ในตัวอย่างนี้ การเรียก next('Apple') จะส่งค่า 'Apple' ไปยังฟังก์ชัน Generator ซึ่งค่าดังกล่าวจะถูกใช้งานภายในฟังก์ชัน

การจัดการสถานะของ Generator

Generators สามารถรักษาสถานะระหว่างการทำงานของตน ซึ่งช่วยให้การแสดงผลของลูปยาวหรือการประมวลผลแบบลำดับมีความกระชับ ตัวอย่างต่อไปนี้แสดงการทำงานของ generator ที่สร้างตัวเลขอย่างไม่สิ้นสุด

 1function* infiniteGenerator() {
 2    let i = 0;
 3    while (true) {
 4        yield i++;
 5        if (i > 10) {
 6            break;
 7        }
 8    }
 9}
10
11const gen = infiniteGenerator();
12
13console.log(gen.next().value); // 0
14console.log(gen.next().value); // 1
15console.log(gen.next().value); // 2
16// Continues...

generator นี้สร้างตัวเลขอย่างต่อเนื่องโดยใช้ลูป while(true) ทำให้คุณสามารถรับค่าได้ตามต้องการ สิ่งนี้ช่วยให้การประมวลผลชุดข้อมูลขนาดใหญ่มีประสิทธิภาพมากขึ้น

การใช้งานของฟังก์ชัน Generator

ฟังก์ชัน Generator เหมาะสำหรับการดำเนินขั้นตอนการประมวลผลหลายขั้นตอนแบบตามลำดับ ตัวอย่างเช่น ฟังก์ชันเหล่านี้มีประโยชน์ในการประมวลผลคำร้อง API แบบตามลำดับหรือการแบ่งและประมวลผลไฟล์ขนาดใหญ่

1function* apiRequestGenerator() {
2    yield fetch('https://codesparklab.com/json/example1.json');
3    yield fetch('https://codesparklab.com/json/example2.json');
4    yield fetch('https://codesparklab.com/json/example3.json');
5}

ดังนั้น generator ที่สามารถใช้สำหรับการประมวลผลแบบอะซิงโครนัสจึงมีประโยชน์อย่างมากในการจัดการข้อมูลแบบตามลำดับอย่างมีประสิทธิภาพ

Asynchronous Generators

Asynchronous generators ซึ่งถูกนำมาใช้ใน ES2018 ช่วยให้คุณสามารถคืนค่าที่เป็นอะซิงโครนัสแบบตามลำดับได้โดยการรวม async และ yield สิ่งนี้ทำให้สามารถเขียนกระบวนการประมวลผลแบบอะซิงโครนัสได้อย่างกระชับโดยใช้ร่วมกับ await

ไวยากรณ์

 1async function* asyncGenerator() {
 2    yield await Promise.resolve(1);
 3    yield await Promise.resolve(2);
 4    yield await Promise.resolve(3);
 5}
 6
 7const gen = asyncGenerator();
 8
 9(async () => {
10    for await (const value of gen) {
11        console.log(value); // 1, 2, 3
12    }
13})();

Asynchronous generators สามารถดึงค่าต่าง ๆ ตามลำดับโดยใช้ลูป for await...of รูปแบบนี้มีประโยชน์อย่างยิ่งเมื่อจัดการกับข้อมูลสตรีมแบบอะซิงโครนัส

ตัวอย่างการใช้งานจริง: การทำให้การประมวลผลแบบอะซิงโครนัสง่ายขึ้นด้วย Generators

ฟังก์ชัน Generator ยังถูกใช้เพื่อลดความซับซ้อนของกระบวนการประมวลผลแบบอะซิงโครนัส ตัวอย่างเช่น โดยการรวม yield และ Promise ดังตัวอย่างด้านล่าง คุณสามารถเขียนการดำเนินการแบบอะซิงโครนัสให้ดูเหมือนเป็นแบบซิงโครนัสได้

 1function* asyncFlow() {
 2    const data1 = yield fetch('https://codesparklab.com/json/example1.json');
 3    console.log(data1);
 4    const data2 = yield fetch('https://codesparklab.com/json/example2.json');
 5    console.log(data2);
 6}
 7
 8const gen = asyncFlow();
 9
10function handleAsync(generator) {
11    const next = (promise) => {
12        promise.then((result) => {
13        const { value, done } = generator.next(result);
14        if (!done) {
15            next(value);
16        }
17        });
18    };
19
20    next(generator.next().value);
21}
22
23handleAsync(gen);

โค้ดนี้ทำการร้องขอ API แบบตามลำดับโดยใช้ generator และประมวลผลผลลัพธ์

สรุป

ฟังก์ชัน Generator เป็นหนึ่งในฟีเจอร์ที่ทรงพลังของ JavaScript ที่มีความสามารถในการหยุดและเริ่มการทำงานของฟังก์ชันอีกครั้ง สิ่งนี้ช่วยให้สามารถประมวลผลแบบตามลำดับ การประมวลผลแบบอะซิงโครนัส และการจัดการชุดข้อมูลขนาดใหญ่อย่างมีประสิทธิภาพ การเข้าใจ generator เป็นขั้นตอนสำคัญในการเรียนรู้เทคนิคขั้นสูงใน JavaScript

คุณสามารถติดตามบทความข้างต้นโดยใช้ Visual Studio Code บนช่อง YouTube ของเรา กรุณาตรวจสอบช่อง YouTube ด้วย

YouTube Video