קורס JavaScript ES6/7/8 שיעור Async Generators


זה נושא דיון מלווה לערך המקורי ב- https://www.tocode.co.il/bundles/es6/lessons/async-generators

לא הצלחתי להבין מדוע בפונקציה *issLocations הקריאה של ה-yield צריכה להיות בתוך לולאה עם true לקראת הסוף אתה מוסיף עם שורה בתוך הלולאה עם asleep שבלבל אותי קצת יותר.
אתה אומר בסרטון “מכיוון שאנחנו רוצים שהקריאה תתבצע בכל איטרציה”. איטרציה של מה? של הלולאה “for await” או ה-“while”? אם הבנתי נכון Generators אז אלא אם כן תקרא ל-next() המצביע עדיין ישאר באותה נקודה, לכן כל קריאה של הפונקציה issLocations בכל מקרה תעשה את הקריאה לget.

בנוסף אנחנו כביכול עושים לולאה בתוך לולאה. כשהresponse יחזור מה-yield אז כביכול הלולאה תיפסק?

הי עומרי,

הרבה פעמים (וגם בשיעור זה) יש הסבר מרחיב יותר על הנושא בטאב ״טקסט״ שליד הסרטון. בלי קשר לשאלה כאן ממליץ לקרוא גם אותו.

עכשיו לנושא-

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

ה yield בגוף הפונקציה הוא מה שגורם לכל העסק לעבוד. בפונקציה מסוג Async Generator הפונקציה עצמה יכולה להמשיך ולייצר ערכים אבל היא תעשה את זה רק אם תקבל בקשה יזומה מבחוץ. כל ״בקשה״ תמשיך להתקדם בפונקציה עד ה yield הבא ואז תחזיר את השליטה למי שביקש.

ההערה שלך לגבי המצביע היא נכונה. אבל בשביל שבאמת כמו שכתבת ״כל קריאה של הפונקציה בכל מקרה תעשה את הקריאה ל get״ היא חייבת לכלול לולאה אין סופית. אחרת כשהפונקציה תסתיים לא תוכל לקבל יותר ערכים מהסידרה. ה return של הפונקציה מייצג בעצם את סוף הסידרה.

לא הבנתי לגבי for await of
מה שיקרה עכשיו שהוא לא ימשיך לאיבר הבא עד שהפרומיס הנוכחי - יחזיר תשובה - ואם בפרומיס הבא בתור כבר קיבלתי תשובה הכל יתעכב - אז זה לא בדיוק איך שהוא מגיע הוא ידפיס

לא קיבלת תשובה ב Promise הבא כי הוא עדיין לא התחיל לעבוד.

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

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

למה הוא לא התחיל לעבוד - יש לי כבר מערך של כל ההבטחות - עכשיו אני רק מחליט מה יקרה כאשר יסתיימו
לא מבין למה אתה כותב שהוא עדיין לא התחיל לעבוד - ראינו בסרטון שכל הסרטים נשלחו ביחד ?

על איזה מהתוכניות אתה מדבר? תוכל להדביק את הקוד?

import {} from 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js';

async function getData(id) {
    const data = await $.get(`https://swapi.co/api/people/${id}/`);
    const futureFilms = data.films.map(film => $.get(film));

    for await (let film of futureFilms) {
        console.log(film.title);
    }
}

getData(1);

החלק הזה בקוד

const futureFilms = data.films.map(film => $.get(film));

כבר מייצר לי מערך של הבטחות שכבר רצים
החלק הזה בקוד עובר עליהם בהמתנה עבור כל הבטחה ומבצע רישום ללוג

for await (let film of futureFilms) {
        console.log(film.title);
    }

ולכן יכול להיות מצב שההבטחות נגיד מהאיבר השני ומעלה כבר הסתיימו ועדיין לא יבצעו כלום על המסך - כיוון שאני ממתין להבטחה המסובכת שנמצאת נגיד באיבר השני ועד שהיא לא תסתיים לא יקרה כלום

ז"א - שזה לא בדיוק שברגע שההבטחות אכן מסתיימות הקוד שלי יבוצע אלא עדיין אני עובר עליהם אחד אחד כדי לבצע את הפונקציה then שלהם

מדויק

אם אתה רוצה קוד שיבוצע מיד כש Promise מסתיים תוסיף אותו ל then של ה Promise בעצמך.

אם אתה רוצה קוד סידרתי כמו שתיארת לך על לולאת ה for.

ומה אם אני רוצה לייצר מערך של הבטחות - והראשונה שמחזירה תשובה לעצור \ לבטל את שאר ההבטחות?

לא מבטלים הבטחות… כדאי לקרוא כאן