-
לצורך מסוים בתוך סקריפט שאני עורך, רציתי להוסיף השהייה - כלומר שתהיה הודעה מסוימת, ואז המהדר יחכה כמה שניות ואז יפתח כרטיסיה מסוימת.
ניסיתי להשתמש ב-()setTimeout
על פי מה שכתוב פה, אבל בפועל זה לא עבד...
כלומר הקוד רץ, אבל מיידית - לא אחרי כמה שניות...
זה הקוד שכתבתי (בקוד המקורי הוא לא פותח דף בתחומים, אבל משהו דומה...):setTimeout((() => { open(`https://tchumim.com/topic/${topicID}`,"_self"); })(), 3000)
-
@צדיק-תמים אתה מעביר ל setTimeout פונקציית IIFE שמריצה את עצמה אוטומטית. שים לב ש setTimeout צריך לקבל ארגומנט של מה שנקרא 'פונקציית קולבאק'. ואילו אתה מעביר לו כארגומנט את הערך undefined שחוזר מפונקציית ה IIFE שהעברת לו. תסתכל על זה כאילו כתבת ככה:
function openLink(link, target) { open(link, target); } setTimeout( openLink(`https://tchumim.com/topic/${topicID}`,"_self"), 3000 );
אתה בטח מבין לבד שזה לא אמור לעבוד. מה שאתה צריך לעשות זה כמו שכתבתי, להעביר פונקצייה כארגומנט:
function openLink(link, target) { return function () { window.open(link, target); } } setTimeout( openLink(`https://tchumim.com/topic/${topicID}`,"_self"), 3000 );
ראה עוד על IIFE בקישור
-
@מוטי-אורן תודה רבה על ההסבר המפורט...
האמת שניסיתי גם כפונקציה לא אנונימית, אבל זה לא עבד...
כנראה בגלל שלא הוספתי את שורה 2 ו4:return function () { }
(גם כתבתי open ישר, ולא window.open, אבל זה למיטב ידיעתי לא מעכב...)
מה תפקידה של השורה הזאת?
כלומר - למה צריך אותה?
הרי return מיועד להחזיר מידע, אבל אפשר גם לכתוב ישר את הקוד שיבוצע בקריאה לפונקציה... -
@צדיק-תמים אני ינסה להבהיר לך קצת לגבי המנגנון של קולבאקים, אני חושב שזה מה שמסבך אותך.
תנסה להבין שניה את ההבדל בין שני ה setTimeoute הבאים:
function sayHello() { console.log('Hi!'); } setTimeout(sayHello, 1000); // תקין setTimeout(sayHello(), 100); // לא תקין
מה ההבדל ביניהם? תזכור תמיד. כשאתה רואה שם של פונקציה בלי סוגריים, זה אומר שלא מדובר בקריאה לפונקציה, אלא ברפרנס לפונקציה (בקיצור, תחשוב על זה כמו משתנה שמכיל את הפונקציה).
אי לכך ובהתאם לזאת. כשיש לך פונקציה כמו setTimeout שמצפה לקבל פונקציה, אתה צריך להעביר לה את המשתנה המכיל את הפונקצייה, ולא את הערך שהפונקציה מחזירה. מה שאני עשיתי בקוד שהבאתי בפוסט הקודם, הוא פשוט לקחת את הפונקציה של openLink, ולהחזיר באמצעותה ערך שהוא עצמו פונקציה, ולכן זה עבד. הדבר הזה מקובל מאוד בהרבה מקרים ב JS, ולכן הרשיתי לעצמי לעשות את זה.
ממליץ לך לקרוא עוד לגבי המנגנון של callbacks ב JS כאן.
-
@מוטי-אורן בעקבות שאלה בפרטי, אני רואה לנכון להבהיר עד טיפה על דבריך.
הסיבה שבעצם לא צריך את הסוגריים - שמשמעותם כידוע היא קריאה לפונציה, היא מפני שלא אני זה שקורא לפונקציה. האובייקט טיימר הוא זה שקורא לפונקציה, והוא עושה זאת לאחר הזמן הקצוב שהוגדר לו.
לפיכך, עליך להעביר לפונקציית הטיימר 2 פיסות מידע: 1. איזו פונקציה עליו להפעיל. 2. פרק הזמן שעליו להמתין לפני שהוא קורא לפונקציה.
אלו 2 הארגומנטים שאתה שולח לפונקציה setTimeout (או setInterval).2 נקודות נוספות:
-
ואם ישאל השואל, מה אם אני רוצה להעביר ארגומנטים אל תוך הפונקציה שאני רוצה להפעיל? באין סוגריים - אין ארגומנטים.
מתכנתי JS חשבו על זה, ובעצם לאחר 2 הארגומנטים שאתה מעביר לפונקציית הטיימר (כמפורט לעיל) יש לך אפשרות להעביר אגרומנטים נוספים, ללא הגבלה. מהארגומנט השלישי והלאה - אלו ארגומנטים שפונקציית הטיימר תשלח אל תוך הקולבק. -
יש אפשרות לשלוח פונקציה אנונימית לתוך במקום משתנה שמכיל פונקציה. זה בעצם מה שעשית בקוד הראשון בשאלה, רק ששם כפי שמוטי אמר שיבצת את זה בתוך פונקציה שמריצה את עצמה, מה שזהה למסירת פונקציה עם סוגריים - כלומר קורא לפונקציה ומעביר את הערך שהיא מחזירה במקום את הפונקציה עצמה.
-
-
@davidnead תודה.
רק אציין לתועלת הבאים אחריי, שבמה שדוד כתב שאפשר לשים
פונקציה אנונימית, כוונתו הייתה לדבר כזה לדוגמה:setTimeout((() => { open(`https://tchumim.com/topic/${topicID}`,"_self"); }), 3000)
ששונה מהקוד הראשון שהובא בשאלה שלי, רק בהורדת ה-
()
שמריץ אותה. -
@צדיק-תמים אמר בפונקציית השהייה (setTimeout) לא משהה בפועל...:
setTimeout((() => { open(
https://tchumim.com/topic/${topicID}
,"_self"); }), 3000)ליתר דיוק:
setTimeout(() => { open(`https://tchumim.com/topic/${topicID}`,"_self"); }, 3000)
אין משמעות לעטיפה בסוגריים.
-