Interrompi setInterval call in JavaScript


1399

Sto usando setInterval(fname, 10000);per chiamare una funzione ogni 10 secondi in JavaScript. È possibile smettere di chiamarlo per qualche evento?

Voglio che l'utente sia in grado di interrompere il ripetuto aggiornamento dei dati.

Risposte:


2160

setInterval()restituisce un ID intervallo, che è possibile passare a clearInterval():

var refreshIntervalId = setInterval(fname, 10000);

/* later */
clearInterval(refreshIntervalId);

Vedi i documenti per setInterval()e clearInterval().


42
Come è possibile riavviarlo dopo aver terminato con 'clearInterval ()'? Se provo a riavviarlo, ottengo 2x il setInterval in esecuzione.
Dan

8
Anch'io ogni volta che voglio usare SetInterval (MyFunction, 4000); diventa sempre più veloce, ogni volta 2 volte più veloce :( come posso riavviare un setinterval ??
Alireza Masali

14
SetInterval () non cambia la velocità con cui lo passi. Se qualunque cosa stia facendo accelera ogni volta che chiami SetInterval (), allora hai più timer che sono in esecuzione allo stesso tempo e dovrebbero aprire una nuova domanda.
EpicVoyage,

29
Assicurati di fermarlo davvero. A causa dell'ambito variabile, potresti non avere l'ID giusto da chiamare clearInterval. Ho usato al window.refreshIntervalIdposto di una variabile locale e funziona benissimo!
osa,

2
Ho iniziato a collegare l'handle setInterval al suo elemento associato (se pertinente): $('foo').data('interval', setInterval(fn, 100));e quindi cancellandolo con clearInterval($('foo').data('interval'));Sono sicuro che esiste un modo non jQuery per farlo.
Michael - Dov'è Clay Shirky il

105

Se si imposta il valore restituito su setIntervalsu una variabile, è possibile utilizzare clearIntervalper arrestarlo.

var myTimer = setInterval(...);
clearInterval(myTimer);

Non vedo la differenza tra questa e la risposta di John
Bobtroopo,

51

Puoi impostare una nuova variabile e farla incrementare di ++ (conta una) ogni volta che viene eseguita, quindi uso un'istruzione condizionale per terminarla:

var intervalId = null;
var varCounter = 0;
var varName = function(){
     if(varCounter <= 10) {
          varCounter++;
          /* your code goes here */
     } else {
          clearInterval(intervalId);
     }
};

$(document).ready(function(){
     intervalId = setInterval(varName, 10000);
});

Spero che aiuti ed è giusto.


3
Sono stato sorpreso di apprendere che funziona clearInterval(varName);. Mi aspettavo clearIntervaldi non funzionare quando passava il nome della funzione, pensavo che richiedesse l'ID intervallo. Suppongo che questo possa funzionare solo se si dispone di una funzione denominata, poiché non è possibile passare una funzione anonima come variabile all'interno di se stessa.
Patrick M,

31
In realtà penso che non funzioni. Il codice non viene più eseguito a causa della restrizione sul contatore, ma l'intervallo continua a essere attivato varName (). Prova a registrare qualsiasi cosa dopo clearInterval () (all'interno della clausola else) e vedrai che viene scritto per sempre.
Rafael Oliveira,

5
Così tanti voti positivi per qualcosa che non funziona, a volte non capisco le persone su SO: P
Stranded Kid

2
$(document).ready(function(){ });è jQuery, ecco perché non funziona. Questo avrebbe dovuto essere menzionato almeno.
Paddotk,

4
@OMGrant, oltre a un esempio che non funziona, hai una variabile denominata varName, che memorizza una funzione senza nome - wha ?? Dovresti cambiare o eliminare questa risposta, IMHO.
Dean Radcliffe,

13

Le risposte sopra hanno già spiegato come setInterval restituisce un handle e come questo handle viene utilizzato per annullare il timer intervallo.

Alcune considerazioni architettoniche:

Non utilizzare variabili "senza ambito". Il modo più sicuro è utilizzare l'attributo di un oggetto DOM. Il posto più semplice sarebbe "documento". Se l'aggiornamento è avviato da un pulsante di avvio / arresto, è possibile utilizzare il pulsante stesso:

<a onclick="start(this);">Start</a>

<script>
function start(d){
    if (d.interval){
        clearInterval(d.interval);
        d.innerHTML='Start';
    } else {
        d.interval=setInterval(function(){
          //refresh here
        },10000);
        d.innerHTML='Stop';
    }
}
</script>

Poiché la funzione è definita nel gestore dei clic sui pulsanti, non è necessario definirla di nuovo. Il timer può essere ripreso se si fa nuovamente clic sul pulsante.


1
Cosa c'è di meglio di metterlo su documentche su window?
icktoofay,

1
correzione. Volevo dire document.body. Nel mio esempio di codice sto effettivamente usando il pulsante stesso. Non esiste un ID per il pulsante, ma il puntatore "this" è associato al parametro "d" nella funzione. L'uso di "finestra" come ambito è rischioso perché ci sono anche funzioni. Ad esempio, "function test () {}" è accessibile tramite window.test, che equivale a non utilizzare affatto un ambito, poiché è una scorciatoia. Spero che sia di aiuto.
Schien,

1
non perdere variabili "senza ambito" -> non usare "senza ambito" L'avrei modificato, ma la modifica è inferiore a 6 lettere e l'errore è confuso.
Leif Neland,

2
Non hai bisogno di DOM per questo. Solo noi un IIFE per evitare l'inquinamento di portata globale.
Onur Yıldırım,

1
Devo aggiungere 'd.interval = undefined' dopo innerhtml = 'start' per farlo funzionare di nuovo. Perché così funziona solo una volta.
giovedì

11

Ho già risposto ... Ma se hai bisogno di un timer in primo piano e riutilizzabile che supporti anche più attività su intervalli diversi, puoi usare il mio TaskTimer (per Nodo e browser).

// Timer with 1000ms (1 second) base interval resolution.
const timer = new TaskTimer(1000);

// Add task(s) based on tick intervals.
timer.add({
    id: 'job1',         // unique id of the task
    tickInterval: 5,    // run every 5 ticks (5 x interval = 5000 ms)
    totalRuns: 10,      // run 10 times only. (omit for unlimited times)
    callback(task) {
        // code to be executed on each run
        console.log(task.name + ' task has run ' + task.currentRuns + ' times.');
        // stop the timer anytime you like
        if (someCondition()) timer.stop();
        // or simply remove this task if you have others
        if (someCondition()) timer.remove(task.id);
    }
});

// Start the timer
timer.start();

Nel tuo caso, quando gli utenti fanno clic per disturbare l'aggiornamento dei dati; è anche possibile chiamare timer.pause()allora timer.resume()se hanno bisogno per riattivare.

Vedi di più qui .


6

Il metodo clearInterval () può essere utilizzato per cancellare un set di timer con il metodo setInterval ().

setInterval restituisce sempre un valore ID. Questo valore può essere passato in clearInterval () per arrestare il timer. Ecco un esempio di timer che parte da 30 e si ferma quando diventa 0.

  let time = 30;
  const timeValue = setInterval((interval) => {
  time = this.time - 1;
  if (time <= 0) {
    clearInterval(timeValue);
  }
}, 1000);

5

@cnu,

Puoi interrompere l'intervallo, quando prova a eseguire il codice prima di guardare il tuo browser della console (F12) ... prova a commentare clearInterval (trigger) è ancora una volta una console, non un beautizer? : P

Controlla l'esempio una fonte:

var trigger = setInterval(function() { 
  if (document.getElementById('sandroalvares') != null) {
    document.write('<div id="sandroalvares" style="background: yellow; width:200px;">SandroAlvares</div>');
    clearInterval(trigger);
    console.log('Success');
  } else {
    console.log('Trigger!!');
  }
}, 1000);
<div id="sandroalvares" style="background: gold; width:200px;">Author</div>


3

Dichiara la variabile per assegnare il valore restituito da setInterval (...) e passa la variabile assegnata a clearInterval ();

per esempio

var timer, intervalInSec = 2;

timer = setInterval(func, intervalInSec*1000, 30 ); // third parameter is argument to called function 'func'

function func(param){
   console.log(param);
}

// Ovunque tu abbia accesso al timer dichiarato sopra chiama clearInterval

$('.htmlelement').click( function(){  // any event you want

       clearInterval(timer);// Stops or does the work
});

1
var keepGoing = true;
setInterval(function () {
     if (keepGoing) {
        //DO YOUR STUFF HERE            
        console.log(i);
     }
     //YOU CAN CHANGE 'keepGoing' HERE
  }, 500);

Puoi anche interrompere l'intervallo aggiungendo un listener di eventi per dire un pulsante con l'ID "intervallo di arresto":

$('buuton#stop-interval').click(function(){
   keepGoing = false;
});

HTML:

<button id="stop-interval">Stop Interval</button>

Nota: l'intervallo verrà comunque eseguito, tuttavia non accadrà nulla.


2
Questo è davvero tornato per le prestazioni, e per le schede in background, in realtà rallenterà di molto tutti gli altri timer poiché i timer e gli intervalli sono
ridotti

1

Ecco come ho usato il metodo clearInterval () per fermare il timer dopo 10 secondi.

function startCountDown() {
  var countdownNumberEl = document.getElementById('countdown-number');
  var countdown = 10;
  const interval = setInterval(() => {
    countdown = --countdown <= 0 ? 10 : countdown;
    countdownNumberEl.textContent = countdown;
    if (countdown == 1) {
      clearInterval(interval);
    }
  }, 1000)
}
<head>
  <body>
    <button id="countdown-number" onclick="startCountDown();">Show Time </button>
  </body>
</head>


1

Utilizzare setTimeOut per interrompere l'intervallo dopo qualche tempo.

var interVal = setInterval(function(){console.log("Running")  }, 1000);
 setTimeout(function (argument) {
    clearInterval(interVal);
 },10000);

0

Immagino che il seguente codice ti aiuterà:

var refreshIntervalId = setInterval(fname, 10000);

clearInterval(refreshIntervalId);

Hai corretto il codice al 100% ... Quindi ... Qual è il problema? O è un tutorial ...


-3

Perché non usare un approccio più semplice? Aggiungi un corso!

Aggiungi semplicemente una classe che dice all'intervallo di non fare nulla. Ad esempio: al passaggio del mouse.

var i = 0;
this.setInterval(function() {
  if(!$('#counter').hasClass('pauseInterval')) { //only run if it hasn't got this class 'pauseInterval'
    console.log('Counting...');
    $('#counter').html(i++); //just for explaining and showing
  } else {
    console.log('Stopped counting');
  }
}, 500);

/* In this example, I'm adding a class on mouseover and remove it again on mouseleave. You can of course do pretty much whatever you like */
$('#counter').hover(function() { //mouse enter
    $(this).addClass('pauseInterval');
  },function() { //mouse leave
    $(this).removeClass('pauseInterval');
  }
);

/* Other example */
$('#pauseInterval').click(function() {
  $('#counter').toggleClass('pauseInterval');
});
body {
  background-color: #eee;
  font-family: Calibri, Arial, sans-serif;
}
#counter {
  width: 50%;
  background: #ddd;
  border: 2px solid #009afd;
  border-radius: 5px;
  padding: 5px;
  text-align: center;
  transition: .3s;
  margin: 0 auto;
}
#counter.pauseInterval {
  border-color: red;  
}
<!-- you'll need jQuery for this. If you really want a vanilla version, ask -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<p id="counter">&nbsp;</p>
<button id="pauseInterval">Pause</button></p>

Ho cercato questo approccio semplice e veloce per anni, quindi sto pubblicando diverse versioni per presentare quante più persone possibile.


17
Non mi sembra molto più semplice ... Penso anche che sia più pulito rimuovere i tuoi intervalli invece di mantenere chiamate a funzioni che non fanno nulla.
Romain Braun,

Non sono d'accordo this.setInterval(function() { if(!$('#counter').hasClass('pauseInterval')) { //do something } }, 500);è tutto ciò che hai per il codice. Inoltre, il controllo è la prima cosa che fai, quindi è molto leggero quando viene sospeso. Ecco a cosa serve questo: mettere temporaneamente in pausa una funzione . Se vuoi terminarlo indefinitamente: ovviamente rimuovi l'intervallo.
Aart den Braber,

Ciò equivale a polling ed è generalmente scoraggiato. Riattiverà la CPU da stati di bassa potenza solo per fare un (probabilmente) controllo inutile. In questo esempio, ritarda anche il feedback da immediato a tra 0 e 500 ms.
Charlie,

Non sono assolutamente d'accordo con te, anche se ho scritto il codice 2 anni fa. Il contatore deve essere lì comunque, perché l'OP lo ha richiesto. Certo, se lo stai usando per fermare il contatore dopo aver premuto un pulsante, ad esempio, questa sarebbe una soluzione non ottimale, ma solo per una pausa durante il passaggio del mouse, questa è una delle soluzioni più semplici disponibili.
Aart den Braber,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.