קורס Front End למתכנתים שיעור תרגול HTML Audio


זהו נושא דיון מלווה לערך המקורי שב־https://www.tocode.co.il/bundles/frontend/lessons/html-audio-lab

שלום,
מצרפת את התרגיל השני - משחק הכסאות.
בפונקציה startAudioAndRaffleNumToStop אני משתמשת ב-promise עבור טיימר שמפסיק את המנגינה.
השאלה שלי האם יש דרך יותר קצרה לכתוב את כל הפונקציה בתוך ה-then כך שה-this יהיה ה-Game, בלי הצורך להגדיר את הפונקציה מבחוץ?
אותה הבעיה היתה לי בפונקציה - startTimeReturnPromise שמחזירה את ה-promise.
כאשר כתבתי את הפונקציה כולה בתוך ה-new Promise, כשניסיתי להשתמש שם ב-this הוא היה undefine,
אשמח לתשובות וגם להערות על הפתרון.
תודה רבה!

נ.ב - האם בקורס החדש יש שעור על promise? לא מצאתי אותו…

HTML

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF8">
        <link rel="stylesheet" href="chairsGame.css">
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
    </head>
    <body>
        <h2 id="title">משחק הכסאות</h2>
        <button class="btnStart">התחל  במשחק</button>
        <div class="container">
            
        </div>
        <button class="btnAgain"> נגן שוב והורד כסא </button>
        <script src="chairsGame.js"></script>
    </body>
</html>

CSS

#title {
    margin: 55px;
    text-align: center;
}

img{
    display: none;
}

.btnStart {
    margin-left: calc(50% - 58px);
}

.btnAgain{
    display: none;
    margin-top: 55px;
    margin-left: calc(50% - 58px);
}

.container {
    text-align: center;
    font-size: 100px;
}

JS

class Game {
    constructor(container,ammountOfChairs) {
        this.btnStart = document.querySelector('.btnStart');
        this.btnAgain = document.querySelector('.btnAgain');

        this.ammountOfChairs = ammountOfChairs;
        this.container = container;
        this.myAudio = new Audio ("song.mp3");
        this.numToStopAudio = 0;

        this.btnStart.addEventListener('click',this.startGame.bind(this));
        this.btnAgain.addEventListener('click',this.againGame.bind(this));
    }
    
    startGame() {
        this.btnStart.style.display = 'none';
        this.createImages();
        this.startAudioAndRaffleNumToStop();
    }

    createImages() {
        const frag = document.createDocumentFragment();  
        for(let i=0 ;i<this.ammountOfChairs;i++) {
            const img = document.createElement('img');
            img.src = "chair.jpg";
            img.style.width = `${100/this.ammountOfChairs}%`;
            img.style.display ='inline-block';
            frag.appendChild(img);
        }
        this.container.innerHTML = '';
        this.container.appendChild(frag);
    }
    
    raffle() {
        this.numToStopAudio = Math.floor(Math.random()*20);
    }

    startAudioAndRaffleNumToStop() {
        this.myAudio.play();
        this.raffle();
        this.startTimeReturnPromise().then(this.afterEndTime.bind(this));
    }

    afterEndTime() {
        this.myAudio.pause();
        this.myAudio.currentTime = 0;
        this.btnAgain.style.display = 'block';
    }

    setTimeOutStart(resolve) {
        setTimeout(resolve,this.numToStopAudio*1000);
    }

    startTimeReturnPromise() {
        return new Promise(this.setTimeOutStart.bind(this));
    }

    againGame() {
        this.btnAgain.style.display = 'none';
        this.ammountOfChairs--;
        if(this.ammountOfChairs>0) {
            this.createImages();
            this.startAudioAndRaffleNumToStop();
        }
        else{
            this.container.innerHTML = '- - - סוף - - -';
        }
    }
}

const container = document.querySelector('.container');
const gameChairs = new Game(container,10);

רק להבין, הקורס הנוכחי זה “הקורס החדש”?
רק לוודא שלא מפספסת משהו…

הי כן זה הקורס העדכני:
https://www.tocode.co.il/bundles/frontend/toc

אני ממליץ בסיום הצפייה להסתכל גם על קורס EcmaScript כאן:
https://www.tocode.co.il/bundles/es6/toc

שם אני מסביר על יכולות נוספות של JavaScript שלדעתי לא היו מספיק מהותיות לקורס Front End אך הן כן נדרשות כדי להתקדם לעבודה עם React (או פריימוורקים אחרים)