Search code examples
javascriptangularionic-frameworkionic4

javascript loop array with setTimeout


I'm developing simple game on Ionic and Angular where you have to press a button once a sequence of lights switched off. I have 5 columns with 4 circles inside. I want:

  • Turn on the last two lights of each colun starting by the left with a two second delay between each column
  • When this is done and all the lights are switched then on two seconds later all the lights should switch off and the user has to press a button.

At ths point I have done the first step using a setTimeOut and a Promise but the code isn't waiting to end the lights on sequencie to run the turn lights off code line.

This is my html:

<ion-grid>
    <ion-row>
      <ion-col size='2' class='light-background'>
        <div class="light"></div>
        <div class="light"></div>
        <div class="light round-1"></div>
        <div class="light round-1"></div>
      </ion-col>
      <ion-col size='2' class='light-background'>
        <div class="light"></div>
        <div class="light"></div>
        <div class="light round-2"></div>
        <div class="light round-2"></div>
      </ion-col>
      <ion-col size='2' class='light-background'>
        <div class="light"></div>
        <div class="light"></div>
        <div class="light round-3"></div>
        <div class="light round-3"></div>
      </ion-col>
      <ion-col size='2' class='light-background'>
        <div class="light"></div>
        <div class="light"></div>
        <div class="light round-4"></div>
        <div class="light round-4"></div>
      </ion-col>
      <ion-col size='2' class='light-background'>
        <div class="light"></div>
        <div class="light"></div>
        <div class="light round-5"></div>
        <div class="light round-5"></div>
      </ion-col>
    </ion-row>
  </ion-grid>

This is the controller:

// Luces a encender
  lightsList = ['.round-1', '.round-2', '.round-3', '.round-4', '.round-5'];

  // Control botones
  isReady = false;

  setButton(){
    this.isReady ? this.isReady = false : this.isReady = true;
  }

  setLightsOff() {
    console.log(`start lights off`);
  }

  startLight(light: string){
    let lights = document.querySelectorAll(light);
    console.log(`parametro entrada: ${light}`);
    
    for(let i=0; i < lights.length; i++){
      lights[i].classList.add('red-light');
    }
  }

  startSequence(){
    return new Promise(resolve => {

      this.lightsList.forEach((light, i) => {

        setTimeout(() => {
          this.startLight(light);
          console.log(`end`);
          
        }, i * 2000);

        resolve('resolved');
        
      });
      
    })
    
  }

  start(){
    this.setButton();

    this.startSequence().then(this.setLightsOff);

  }

  run(){
    this.setButton();
  }

On the view there's two buttons, the first one starts the light sequence, the secod one it's the one the user has to press once the lightns are turned off. When pressing th start button a function called start() is launched and executes a setButton function which disables de start button and enables the run button (the one to press when the lights are off) and launches the function startSequence which reads the array of lights and calls the function that add a new class to the lights so the look like they are turned on.


Solution

  • try async await for this task

    wait(time) {
      return new Promise(resolve => setTimeout(resolve, time));
    }
    async startSequence(){
      for(let light of lights) {
          await this.wait(2000);
          this.startLight(light);
      }
    }