Necesito ayuda, el botón de detención invoca clearInterval () y solo funciona una vez, ¿qué tiene de malo el código?

var start = document.querySelector("#start");
var stop = document.querySelector("#stop");

window.addEventListener('load', () => {

  function intervalo() {
    var tiempo = setInterval(function() {
    console.log("Set interval ejecutado");
  }, 1500);
    return tiempo;
  }

  var tiempo = intervalo();
  
  stop.addEventListener("click", function() {   
    clearInterval(tiempo);
  });

  start.addEventListener("click", function() {
    intervalo();
  });
});
<button id="stop"> stop! </button>
<button id="start"> start! </button>
3
sonEtLumiere 26 jun. 2020 a las 07:59

4 respuestas

La mejor respuesta

Parece que se llama a setInterval varias veces y, por lo tanto, se producen varios temporizadores simultáneamente; una versión más limpia sería:

let tiempo; 

const start = () => {
  console.log("starting...")
  if(!tiempo) {
    tiempo = setInterval(
      ()=> {console.log("interval")}
    , 1000)  
  }
}

const stop = () => {
  console.log("stopped")
  clearInterval(tiempo);
  tiempo = null; 
}
<button onclick="stop()"id="stop"> stop! </button>
<button onclick="start()" id="start"> start! </button>
4
Pavlos Karalis 29 jun. 2020 a las 23:13

Debido a que configura una vez su variable tiempo, debe configurarla nuevamente con su función de intervalo

var start = document.querySelector("#start");
var stop = document.querySelector("#stop");

window.addEventListener('load', () => {

  function intervalo() {
    return setInterval(function() {
       console.log("Set interval ejecutado");
    }, 1500);
  }
  var timer = true;
  var tiempo = intervalo();
  
  stop.addEventListener("click", function() {   
    clearInterval(tiempo);
    timer = false;
  });

  start.addEventListener("click", function() {
    if(timer == false) {
       tiempo = intervalo();
       timer = true;
    }
  });
});
<button id="stop"> stop! </button>
<button id="start"> start! </button>
1
H.Rafiee 26 jun. 2020 a las 05:21

Su nombre de variable es muy confuso y anula setInterval anterior id con uno más nuevo cada vez; entonces sugiero usar una estructura de nombres más clara para evitar tal escenario;

var start = document.querySelector("#start");
var stop = document.querySelector("#stop");
var intervalRefId;
window.addEventListener('load', () => {

  function intervalo() {
    return setInterval(function() {
      console.log("Set interval ejecutado");
    }, 1500);
  }

  intervalRefId = intervalo();
  
  stop.addEventListener("click", function() {   
    clearInterval(intervalRefId);
  });

  start.addEventListener("click", function() {
    intervalRefId = intervalo();
  });
});
<button id="stop"> stop! </button>
<button id="start"> start! </button>
1
Leonardo 26 jun. 2020 a las 05:04

¿Notó que var tiempo = setInterval(function() {..}) se declaró dentro de function intervalo()? Entonces su alcance está en la función intervalo.

Pero otro var tiempo = intervalo() se declara fuera del intervalo, dos variables tiemp son diferentes, por eso clearInterval(tiempo); no funciona.

¿Por qué funciona por primera vez? Porque cuando DOM se cargó y emitió el evento load una vez, dentro de esa función, configuró var tiempo = intervalo(), y se configuró una sola vez hasta que lo borró. La próxima vez que haga clic en start: fuera de tiempo no se configuró nada.

La "solución" es simple: declarar tiemp en la parte superior de la devolución de llamada load, luego establecer it igual intervaloId return de setInterval.

var start = document.querySelector("#start");
var stop = document.querySelector("#stop");

window.addEventListener('load', () => {
  var tiempo;
  function intervalo() {
    //tiempo was declared in this function's closure
    tiempo = setInterval(function() {
    console.log("Set interval ejecutado");
  }, 1500);
  }

  
  stop.addEventListener("click", function() {   
    //tiempo was declared in this function's closure
    clearInterval(tiempo);
  });

  start.addEventListener("click", function() {
    intervalo();
  });
});

P / s: lea más sobre scope en javascript, especialmente closure.

2
Kai 26 jun. 2020 a las 06:32