How to stop for...of loop immediately after an element is displayed on the page?

67 Views Asked by At

I even had to create account on Stackoverflow, because I couldn't find the solution for my problem. I'm a newbie in JS and programming in general. Here's the issue - I have a JS function that plays the battleship game via UI with a bunch of for...of loops and if statements:

    async playGame(cords) {
        for (let cord of cords) {
            const cellStateBeforeClick = await this.getCellState(cord);
            if (cellStateBeforeClick.includes('empty')) {
                const cellStateAfterClick = await this.clickCellAndGetState(cord);
                if (
                    cellStateAfterClick.includes('hit') &&
                    cellStateAfterClick.includes('last') &&
                    !cellStateAfterClick.includes('done')
                ) {
                    const offsetCells = await this.checkNearestCells(cord);
                    for (let cord of offsetCells) {
                        const nextCellStateBeforeClick = await this.getCellState(cord);
                        if (!nextCellStateBeforeClick.includes('done')) {
                            const nextCellStateAfterClick = await this.clickCellAndGetState(cord);
                        if (
                            nextCellStateAfterClick.includes('hit') &&
                            nextCellStateAfterClick.includes('last') &&
                            !nextCellStateAfterClick.includes('done')
                        ) {
                            const shipOrientation = await this.determineShipOrientation(cord, hitCells);
                            const nearestCells = await this.checkNearestCells(cord);
                            for (let cord of nearestCells) {
                                await this.hitStraightLine(cord, shipOrientation);
                            }
                        }
                        }
                    }
                }
            }
        }
    }

The game ends when I win or lose, or when the enemy leaves. When one of these events happen, a notification appears on the page (DOM doesn't change, it just displays). Here's the function to get one of these notifications:

    async isNotificationDisplayed() {
        if (
            this.isWinNotificationDisplayed() ||
            this.isLoseNotificationDisplayed() ||
            this.isLeaveNotificationDisplayed()
        ) {
            return true;
        }
    }

So, now I need to somehow implement this: if the notification is displayed, the playGame function should break immediately (notification can appear at any moment, so it should break out of the loop without waiting for any iteration to end). I suspect that I need to run these two functions asynchronously (in parallel), but I couldn't understand how to do this. I tried a lot of different ways, but none of them worked as I needed. What is the best solution?

I tried Promises, Promise.race, and a lot of other options I can't even remember at the moment. The main issue with all of them was this - the playGame checks the condition and then iterates (but because when notification appears, the playfield becomes unclickable, it keeps resulting in error).

0

There are 0 best solutions below