גנרטורים – החלקים החריפים

טיוטת המפרט של ECMAScript 6 כבר סיפקה הרבה רגעים של אושר למפתחי JavaScript מודרניים. בפוסט הקודם התייחסנו לכמה כיתות קולקציות חדשות וללולאות איטרציה מסוג for..of. בפוסט הזה נדבר על משהו שנעשה בו שימוש לצד לולאות for..of: פונקציות גנרטורים.

יש מגוון של חומרים מעולים שכבר מוסבר בהם למה צריך להשתמש בגנרטור ואיך עושים את זה. בקצרה, גנרטורים הם פונקציות מיוחדות שיוצרות מחזורים, ומחזורים הם אובייקטים שיש להם את השיטה next(), שאפשר להפעיל כדי לקבל ערך. בתוך פונקציית המחולל, מילת המפתח yield מספקת את הערך של next(). השימוש ב-yield משהה את הביצוע של פונקציית הגנרטור, ושומר את המצב עד שמפעילים שוב את next(). בשלב הזה, הקוד מתחיל לפעול שוב וממשיך עד שהוא yield ערך אחר (או עד שפונקציית הגנרטור מסתיימת). יש כמה תרחישים לדוגמה לשימוש בפונקציות גנרטורים, למשל שימוש בהן כדי להריץ איטרציה על המספרים בסדרת פיבונאצ'י.

אחרי שסיימנו עם העקרונות הבסיסיים, נמשיך לעומק עם דוגמה ל-JavaScript שמראה חלק מהבעיות שעשויות לצוץ בעבודה עם גנרטור. יש תגובות נרחבות לאורך הקוד, ואפשר להתנסות בגרסה הפעילה של הקוד לפני שקוראים אותו:

אז מהן המסקנות העיקריות מהקוד?

קודם כול, יצירה של גנרטור יוצרת איטרטור ייחודי עם מצב ייחודי משלו, ואפשר להעביר פרמטרים ל-constructor של הגנרטור שיכולים לשלוט בהתנהגות.

שנית, אפשר להעביר פרמטר כשקוראים לשיטה next() של מעבד הטבלאות, והערך הזה יוקצה לכל מה שמופיע בצד ימין של משפט yield מהפעלת המעבד הקודמת. זוהי דרך מצוינת לשנות את הפלט של האיטרטור. כאן אנחנו משתמשים בה כדי לקבוע אם המילה שתתקבל תהיה באותיות רישיות או לא. אם רוצים להשפיע על הערך הראשון שיוחזר, עושים זאת באמצעות פרמטר למבנה ה-constructor של המחולל.

לבסוף, גנרטור יכול ליצור מחוללים מוגבלים או אינסופיים. אם אתם עובדים עם מחזור אינסופי, חשוב לוודא שיש לכם תנאי סיום כלשהו שמבוסס על הערך שמשתנה yield. קל מאוד לכתוב בטעות לולאות אינסופיות, במיוחד כשמשתמשים ב-for..of לצורך איטרציה. אם אתם עובדים עם מחזור סופי באמצעות קריאות ל-next(), המאפיין .done של האובייקט המוחזר מאותת אם המחזור הושלם.

אנחנו מקווים שהדוגמה הזו, יחד עם המשאבים האחרים שזמינים באינטרנט, יעזרו לכם להבין איך אפשר להשתמש במחוללים בקוד שלכם. גרסאות של Firefox מ-31 ואילך ושל Chrome מ-39 ואילך תומכות בגנרטורים באופן מקורי. בפרויקט Regenerator יש תמיכה במחוללים לדפדפנים אחרים, ואפשר גם להשתמש ב-Traceur.

תודה ל-Erik Arvidsson על העזרה בבדיקת המאמר הזה.