איך לכתוב sleep ב JavaScript

פוסט זה כולל טיפ קצר בנושא פיתוח Front End. אם אתם רוצים ללמוד יותר לעומק על פיתוח Front End מהבסיס ועד הנושאים המתקדמים תשמחו לשמוע שבניתי קורס וידאו מקיף בנושא זה הכולל מעל 50 שיעורי וידאו והמון תרגול מעשי.
למידע נוסף והצטרפות לקורס בקרו בדף קורס Front End באתר.
 

שאלה שחוזרת אצל מתכנתים שמתחילים לעבוד עם JavaScript היא השאלה לגבי sleep. היינו שמחים לפעמים לכתוב טקסט על המסך, לחכות קצת ואז לכתוב עוד קצת טקסט. בתור שפה אסינכרונית ב JavaScript אי אפשר באמת לעצור את ריצת התוכנית בשביל לחכות. אבל גירסת ES8 של השפה הוסיפה תמיכה ב async/await איתם אפשר לבנות את sleep ואפילו די בקלות.

1. רעיון מרכזי ומימוש

המילה השמורה await מבקשת מ JavaScript לבצע Promise מסוים ולעדכן אותנו כשהתוצאה מוכנה. בזמן שאנחנו מחכים ל Promise התוכנית יכולה להמשיך לטפל באירועים אחרים ולכן לא עוצרת. בשביל ש sleep יהיה משהו שאפשר לשלב אותו עם await הפונקציה sleep שנרצה לכתוב צריכה להחזיר Promise:

function sleep(ms) {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, ms);
  });
}

ה Promise ש sleep מחזירה מתממשת כאשר עובר מספר המילי-שניות שאנחנו ממתינים. בקוד ההבטחה הקריאה ל resolve היא שגורמת להבטחה להתממש ול await המתאים להסתיים.

2. שילוב sleep בתוכנית

ניקח כדוגמא לולאה שכותבת טקסט למסך כמו שמתואר בפונקציה הבאה:

function fillNoDelay() {
  for (let i=0; i < 10; i++) {
    panel.textContent += `Iteration ${i}...`;
  }
}

הפעלה של הפונקציה תרשום את הטקסט כולו בפעולת כתיבה אחת לעמוד. ללא הפקודות async/await היינו יכולים להוסיף השהיה בין כתיבות באמצעות בריחה ממבנה הלולאה ומעבר למבנה רקורסיבי:

function fillWithDelay1(n) {
  panel.textContent += `Iteration ${n}...`;

  if ( n > 0 ) {
    setTimeout(function() {
      fillWithDelay(n - 1);
    }, 150)
  }
}

הבעיה שמבנה זה ממש לא דומה ללולאה שהתחלנו ממנה. לעומת זאת באמצעות await אפשר להישאר עם מבנה הלולאה המוכר ולקבל את הפונקציה:

async function fillWithDelay() {
  for (let i=0; i < 10; i++) {
    panel.textContent += `Iteration ${i}...`;
    await sleep(150);
  }
}

יש כאן את יתרון הקריאות שהקוד הרבה יותר ברור מהגירסא עם ה setTimeout, וחשוב מכך, הרבה יותר קל לעשות שימוש חוזר בפונקציה sleep גם במקומות אחרים.

ככה זה נראה לייב על קודפן. נסו ללחוץ על כפתור Fill With Delay ותראו שאפשר באמצע שהלולאה עובדת להמשיך ללחוץ על כפתורים אחרים, למשל לנקות את הטקסט:

הפקודות async ו await הן לא רק קיצורי דרך קטנים ומועילים. הן שינו את האופן בו אנחנו כותבים קוד ואת המבנים שעובדים או לא עובדים בשפה. אני חושב שהן מהפקודות החשובות ביותר שנכנסו ל JavaScript בשנים האחרונות.

רוצים לדעת יותר על החידושים ב JavaScript ולראות עוד המון דוגמאות מסוג זה? מוזמנים למצוא הכל כאן ובעברית בקורס JavaScript ES6/7/8 שלנו.