פניה אסינכרונית והמסתעף Angular TS
-
@yyy כתב בפניה אסינכרונית והמסתעף Angular TS:
בקיצור לא הולך...
באנגולר לא אמורים לעבוד עם הקונסטרקטור
הקומפוננטה עשויה להיראות כך:export class showBooksComponent implements OnInit { books: Book[]; constructor(private BooksSvc: BooksSvc) { } async ngOnInit() { this.books = await this.BooksSvc.GetBooks(); } }
זה יאפשר לך לבצע מניפולציות על המערך מתוך הקומפוננטה.
באופן כללי עדיף להמנע משימוש ב pipes כמו async ובבינדינג לפונקציות, זה מריץ את הפונקציה בכל בינדינג ודורש יותר משאבים. -
@יוסף-בן-שמעון
עשיתי כדבריך:
זה הסרוויסconstructor(private httpClient: HttpClient) { this.getBooks(); } getBooks() { return this.Books = this.Books || this.httpClient.get<Book[]>(this.GetBooksURL).toPromise(); }
זה הקומפוננטה
constructor( private BookSvc: BookSevice ) { } async ngOnInit() { this.books= await this.BookSvc.getBooks(); }
העניין שכעת לא מתבצעת בכלל פניה לשרת.
האמת (אני מניח שזה קשור לזה) שגם כך אשמח להכיר את הסינטקס של ה-return הנ"ל בשני דברים:
א. סימן ה"||" פירושו OR?
ב. מה המשמעות של קטע הקוד הזה
this.books = this.books
?
תודה רבה. -
@yyy כתב בפניה אסינכרונית והמסתעף Angular TS:
עשיתי כדבריך:
כמעט...
איך נראית השורה הזו בסרביס? כמו האופציה הראשונה או השניה?books: Promise<Book[]>; books: Promise<Book[]> = [];
-
@yyy כתב בפניה אסינכרונית והמסתעף Angular TS:
האמת (אני מניח שזה קשור לזה) שגם כך אשמח להכיר את הסינטקס של ה-return הנ"ל בשני דברים:
א. סימן ה"||" פירושו OR?
ב. מה המשמעות של קטע הקוד הזה
this.books = this.books
?אכן, זה אופרטור OR.
כשאתה מבצע השמה למשתנה books אתה קודם כל בודק אם הוא כבר מאותחל, במידה והוא כבר אותחל אתה לא משנה בו כלום אלא מצביע עליו בחזרה, אם הוא עוד לא מאותחל והוא מחזיר undefined (שזה ערך false ב JS) אז אתה מאתחל אותו כפרומיס.
כך אתה מרויח שהפניה לשרת תתבצע רק פעם אחת בכל חיי האפליקציה, וכל מי שירצה לקבל את רשימת הספרים יקבל אותה מהפרומיס הזה -
@יוסף-בן-שמעון כתב בפניה אסינכרונית והמסתעף Angular TS:
books: Promise<Book[]>;
books: Promise<Book[]> = [];לא כך ולא כך, אלא כך:
books:Books[] = [];
זה:
books: Promise<Books[]>;
מחזיר את השגיאה הזו
'books' has no initializer and is not definitely assigned in the constructor.
ואז אני מוסיף סימן?
ומקבל שגיאה ב-returnType 'Promise<book[] | undefined>' is not assignable to type 'Promise<book[]>'. Type book[] | undefined' is not assignable to type book[]'. Type 'undefined' is not assignable to type book[]'.ts(2322)
וזה:
books: Promise<Book[]> = [];
מחזיר שגיאה:
Type 'never[]' is missing the following properties from type 'Promise<Book[]>': then, catch, finally, [Symbol.toStringTag]
-
@yyy כתב בפניה אסינכרונית והמסתעף Angular TS:
זה:
books: Promise<Books[]>;
מחזיר את השגיאה הזו
'books' has no initializer and is not definitely assigned in the constructor.אתה יכול לכתוב במקום סימן שאלה סימן קריאה, וזה ידלג על הבדיקה
או לאתחל את זה בקונסטקטור בלי האופרטור || ובמתודה getBooks רק להחזיר אותו בלי לעשות השמה -
@יוסף-בן-שמעון כתב בפניה אסינכרונית והמסתעף Angular TS:
כשאתה מבצע השמה למשתנה books אתה קודם כל בודק אם הוא כבר מאותחל,
זה נכון לגבי כל השמה, או שזה משהו ספציפי לפקודת return?
במידה והוא כבר אותחל אתה לא משנה בו כלום אלא מצביע עליו בחזרה,
למה פקודה כזו
return this.books || this.httpClient.get<Books []>(this.Getbooks URL).toPromise();
לא מבצעת אותו דבר, הרי אם האובייקט אינו מאותחל זה יחזיר undefind כלומר false, וילך לפרומיס לאתחל את האובייקט, ואם זה כן מאותחל כלומר true שיחזיר אותו עצמו ולא יפנה לפרומייס?
בדקתי ואכן בסינטקס שלי הוא כן פונה כל פעם מחדש ואני רק שואל למה זה קורה. -
אגב ה-toPromise בהקשר זה הוא depricated
-
@yyy כתב בפניה אסינכרונית והמסתעף Angular TS:
למה פקודה כזו
return this.books || this.httpClient.get<Books []>(this.Getbooks URL).toPromise();
לא מבצעת אותו דבר, הרי אם האובייקט אינו מאותחל זה יחזיר undefind כלומר false, וילך לפרומיס לאתחל את האובייקט, ואם זה כן מאותחל כלומר true שיחזיר אותו עצמו ולא יפנה לפרומייס?
בדקתי ואכן בסינטקס שלי הוא כן פונה כל פעם מחדש ואני רק שואל למה זה קורה.כי אתה אף פעם לא מאתחל אותו.
-
@yyy כתב בפניה אסינכרונית והמסתעף Angular TS:
זה נכון לגבי כל השמה, או שזה משהו ספציפי לפקודת return?
כל השמה
@yyy כתב בפניה אסינכרונית והמסתעף Angular TS:
למה פקודה כזו
returnthis.books || this.httpClient.get<Books []>(this.Getbooks URL).toPromise();
לא מבצעת אותו דבר, הרי אם האובייקט אינו מאותחל זה יחזיר undefind כלומר false, וילך לפרומיס לאתחל את האובייקט, ואם זה כן מאותחל כלומר true שיחזיר אותו עצמו ולא יפנה לפרומייס?
בדקתי ואכן בסינטקס שלי הוא כן פונה כל פעם מחדש ואני רק שואל למה זה קורה.כפי שכתב אהרן, בתחביר שלך אתה לא מאתחל אותו אף פעם, אז הוא תמיד נשאר undefined, ולכן כך קריאה לפונקציה תייצר פניה לשרת.
אם תנסה לפרק את הסינטקס הזה לגורמים, זה יראה כך:getBooks() { if (this.books !== undefined) { return this.books; } else { this.books = this.httpClient.get<Book[]>(this.GetBooksURL).toPromise(); // <<<<<<<<<<<<<<< return this.books; } }
אצלך דילגת על שורה 5, ובמקום זה עשית כך:
getBooks() { if (this.books !== undefined) { return this.books; } else { return this.httpClient.get<Book[]>(this.GetBooksURL).toPromise(); } }
אז books מעולם לא אותחל
-
@יוסף-בן-שמעון
הטעות שלי היית שחשבתי שהתכוונת
לזהreturn (this.Books = this.Books )|| this.httpClient.get<Book[]>(this.GetBooksURL).toPromise();
ולא הבנתי מה ההצבה המוזרה באופרנד הראשון
בשעה שהתכוונת באמת לזה:return this.Books = (this.Books || this.httpClient.get<Book[]>(this.GetBooksURL).toPromise());
-
עכשיו ברשותכם שאלות:
א.
הפונקציה בסרוויסgetBooks() { return this.Books = this.Books || this.httpClient.get<Book[]>(this.GetBooksURL).toPromise(); }
מחזירה פרומיס
אבל הפונקציה בקומפוננטהasync ngOnInit() { this.books= await this.BookSvc.getBooks();
מקבלת []Book ,
השאלה היא האם הסיבה שמתבצעת ההמרה האוטומטית הזו, למרות שמדובר ב-TS, זה בגלל שיש async/await הוא מבין שהוא צריך לחלץ את הערך מהפרומיס?ב. אני מנסה לחבר את פרומיס זה לרעיון הכללי של פרומיס. אני ידעתי שהמצב של הפרומיס מוגדר ע"י הרצת resolve/reject, ואז פונים לthen או catch וכדו'. השאלה היא מי מריץ כאן מאחור את כל הפונקציות האלו הרי בקוד אני לא נוגע כאן ב-resolve then ודומיהם?
-
@yyy המילה await אומרת: קודם תריץ, כשמסתיים תביא לי את הערך החוזר.
זה בעצם מעביר את ההצבה למשתנה לתוך בלוק דמיוני של then לפעולה הפורמיסית.
ממילא:var promise:Promise<number> = new Promise<number>(success => success(555)); var num:number = await promise;
זה שקול לקוד הבא:
var num:number; var promise:Promise<number> = new Promise<number>(success => success(555)); promise.then(function(n){ num = n; });
ואכן בלי המילה await באמת הסוג הוא פרומייס לכל דבר.
ככה זה גם בדיוק בJS (אני בכלל לא מכיר TS).