เชี่ยวชาญโปรโตคอลที่อยู่เบื้องหลัง for...of, spread และ destructuring แล้วใช้ generator เพื่อสร้างลำดับแบบ lazy
เปิดบทเรียนนี้ใน Kodokonมีโปรโตคอลสองอย่างที่แตกต่างกันควบคุมการวนซ้ำ อ็อบเจกต์จะเป็น iterable ถ้ามันเปิดเผยเมท็อดภายใต้คีย์ Symbol.iterator เมท็อดนั้นต้องคืน iterator นั่นคือ อ็อบเจกต์ที่มีเมท็อด next() ซึ่งคืน { value, done } ทุกอย่างที่บริโภคลำดับ - for...of, spread operator ..., destructuring, Array.from, Promise.all - ล้วนผ่านโปรโตคอลเหล่านี้ ดังนั้นคุณจึงทำให้อ็อบเจกต์ใด ๆ เข้ากันได้
const range = {
from: 1,
to: 3,
[Symbol.iterator]() {
let current = this.from;
const last = this.to;
return {
next() {
return current <= last
? { value: current++, done: false }
: { value: undefined, done: true };
}
};
}
};
console.log([...range]); // [1, 2, 3]การเขียน iterator ด้วยมือนั้นยืดยาว Generator (function*) สร้าง iterator ให้โดยอัตโนมัติ แต่ละ yield จะหยุดพักการทำงานและรักษาสถานะโลคัลของฟังก์ชันเอาไว้ การประเมินค่าแบบ lazy นี้ช่วยให้คุณจำลองลำดับที่ไม่มีที่สิ้นสุดได้ ตราบเท่าที่ผู้บริโภคจำกัดจำนวนค่าที่ร้องขอ
function* naturals() {
let n = 0;
while (true) yield n++;
}
function* take(iterable, count) {
let index = 0;
for (const value of iterable) {
if (index >= count) return;
yield value;
index += 1;
}
}
console.log([...take(naturals(), 4)]); // [0, 1, 2, 3]iterator ของ generator ยังเปิดเผย return() และ throw() ด้วย รายละเอียดในสเปกที่มักถูกมองข้าม เมื่อคุณออกจากลูป for...of ด้วย break, return หรือ exception เอนจินจะเรียก iterator.return() ให้ โดยอัตโนมัติ ใน generator สิ่งนี้จะรันบล็อก finally ที่ค้างอยู่ ซึ่งเป็นจุดที่เหมาะสำหรับปล่อยทรัพยากร (ไฟล์ การเชื่อมต่อ ล็อก)
function* readLines() {
try {
yield "line 1";
yield "line 2";
} finally {
console.log("cleanup");
}
}
for (const line of readLines()) {
console.log(line);
break; // triggers return(), hence the finally
}
// line 1, cleanuplength และดัชนีที่เป็นตัวเลขSymbol.iterator ที่คืนอ็อบเจกต์ซึ่งมี next()Array.prototypenext() โดยตรงfor...of ด้วย break ขณะที่มันกำลังบริโภค generator?throw() บน iteratorreturn() ซึ่งรันบล็อก finally ของ generatornext() เท่านั้น