Question

J'ai écrit une fonction javascript qui utilise setInterval pour manipuler une chaîne chaque dixième de seconde pour un certain nombre d'itérations.

function timer() {
    var section = document.getElementById('txt').value;
    var len = section.length;
    var rands = new Array();

    for (i=0; i<len; i++) {
        rands.push(Math.floor(Math.random()*len));
    };

    var counter = 0
    var interval = setInterval(function() {
        var letters = section.split('');
        for (j=0; j < len; j++) {
            if (counter < rands[j]) {
                letters[j] = Math.floor(Math.random()*9);
            };
        };
        document.getElementById('txt').value = letters.join('');
        counter++

        if (counter > rands.max()) {
            clearInterval(interval);
        }
    }, 100);
};

Au lieu d'avoir l'intervalle fixé à un nombre précis, je voudrais le mettre à jour chaque fois qu'il est basé sur un compteur. Ainsi, au lieu de:

var interval = setInterval(function() { ... }, 100);

Il serait quelque chose comme:

var interval = setInterval(function() { ... }, 10*counter);

Malheureusement, cela ne fonctionne pas. Il semblait que "10 * contre" est égal à 0.

Alors, comment puis-je régler l'intervalle chaque fois que la fonction anonyme fonctionne?

Était-ce utile?

La solution

Utilisez setTimeout() à la place. Le rappel serait alors responsable de la mise à feu du prochain délai d'attente, à quel point vous pouvez augmenter ou manipuler le calendrier.

EDIT

Voici une fonction générique que vous pouvez utiliser pour appliquer un délai d'attente « décélérer » pour tout appel de fonction.

function setDeceleratingTimeout(callback, factor, times)
{
    var internalCallback = function(tick, counter) {
        return function() {
            if (--tick >= 0) {
                window.setTimeout(internalCallback, ++counter * factor);
                callback();
            }
        }
    }(times, 0);

    window.setTimeout(internalCallback, factor);
};

// console.log() requires firebug    
setDeceleratingTimeout(function(){ console.log('hi'); }, 10, 10);
setDeceleratingTimeout(function(){ console.log('bye'); }, 100, 10);

Autres conseils

Vous pouvez utiliser une fonction anonyme:

var counter = 10;
var myFunction = function(){
    clearInterval(interval);
    counter *= 10;
    interval = setInterval(myFunction, counter);
}
var interval = setInterval(myFunction, counter);

MISE À JOUR:. Comme suggéré par A. Wolff, utilisez setTimeout pour éviter la nécessité d'clearInterval

var counter = 10;
var myFunction = function() {
    counter *= 10;
    setTimeout(myFunction, counter);
}
setTimeout(myFunction, counter);

J'aime cette question - inspiré un petit objet timer en moi:

window.setVariableInterval = function(callbackFunc, timing) {
  var variableInterval = {
    interval: timing,
    callback: callbackFunc,
    stopped: false,
    runLoop: function() {
      if (variableInterval.stopped) return;
      var result = variableInterval.callback.call(variableInterval);
      if (typeof result == 'number')
      {
        if (result === 0) return;
        variableInterval.interval = result;
      }
      variableInterval.loop();
    },
    stop: function() {
      this.stopped = true;
      window.clearTimeout(this.timeout);
    },
    start: function() {
      this.stopped = false;
      return this.loop();
    },
    loop: function() {
      this.timeout = window.setTimeout(this.runLoop, this.interval);
      return this;
    }
  };

  return variableInterval.start();
};

Exemple utiliser

var vi = setVariableInterval(function() {
  // this is the variableInterval - so we can change/get the interval here:
  var interval = this.interval;

  // print it for the hell of it
  console.log(interval);

  // we can stop ourselves.
  if (interval>4000) this.stop();

  // we could return a new interval after doing something
  return interval + 100;
}, 100);  

// we can change the interval down here too
setTimeout(function() {
  vi.interval = 3500;
}, 1000);

// or tell it to start back up in a minute
setTimeout(function() {
  vi.interval = 100;
  vi.start();
}, 60000);

J'ai eu la même question que l'affiche originale, fait cela comme une solution. Je ne sais pas comment cela est efficace ....

interval = 5000; // initial condition
var run = setInterval(request , interval); // start setInterval as "run"

    function request() { 

        console.log(interval); // firebug or chrome log
        clearInterval(run); // stop the setInterval()

         // dynamically change the run interval
        if(interval>200 ){
          interval = interval*.8;
        }else{
          interval = interval*1.2;
        }

        run = setInterval(request, interval); // start the setInterval()

    }

Ceci est ma façon de le faire, j'utilise setTimeout:

var timer = {
    running: false,
    iv: 5000,
    timeout: false,
    cb : function(){},
    start : function(cb,iv){
        var elm = this;
        clearInterval(this.timeout);
        this.running = true;
        if(cb) this.cb = cb;
        if(iv) this.iv = iv;
        this.timeout = setTimeout(function(){elm.execute(elm)}, this.iv);
    },
    execute : function(e){
        if(!e.running) return false;
        e.cb();
        e.start();
    },
    stop : function(){
        this.running = false;
    },
    set_interval : function(iv){
        clearInterval(this.timeout);
        this.start(false, iv);
    }
};

Utilisation:

timer.start(function(){
    console.debug('go');
}, 2000);

timer.set_interval(500);

timer.stop();

Une façon beaucoup plus simple serait d'avoir une déclaration if dans la fonction rafraîchi et un contrôle pour exécuter votre commande à des intervalles de temps réguliers. Dans l'exemple suivant, je lance une alerte toutes les 2 secondes et l'intervalle (intrv) peuvent être modifiés dynamiquement ...

var i=1;
var intrv=2; // << control this variable

var refreshId = setInterval(function() {
  if(!(i%intrv)) {
    alert('run!');
  }
  i++;
}, 1000);

Réponse simple est vous ne pouvez pas mettre à jour un intervalle de minuterie déjà créé . (Il n'y a que deux fonctions setInterval/setTimer et clearInterval/clearTimer, afin d'avoir un timerId vous ne pouvez le désactiver.) Mais vous pouvez fait quelques solutions de contournement. Jetez un oeil à ce repo github.

Cela peut être lancé comme vous le voulez. délai d'attente est la méthode que je l'habitude de le garder sur le dessus de l'heure.

J'ai eu besoin pour chaque heure pour commencer un bloc de code à l'heure. Donc, cela commence au démarrage du serveur et exécuter l'intervalle horaire. Basiquement la course initiale est de commencer l'intervalle dans la même minute. Ainsi, dans une seconde d'initialisation, exécutez immédiatement puis toutes les 5 secondes.

var interval = 1000;
var timing =function(){
    var timer = setInterval(function(){
        console.log(interval);
        if(interval == 1000){ /*interval you dont want anymore or increment/decrement */
            interval = 3600000; /* Increment you do want for timer */
            clearInterval(timer);
            timing();
        }
    },interval);
}
timing();

Sinon, si vous voulez avoir juste quelque chose se produise au début et puis toujours à un intervalle spécifique, vous pouvez simplement l'appeler en même temps que le setInterval. Par exemple:

var this = function(){
 //do
}
setInterval(function(){
  this()
},3600000)
this()

Ici, nous avons cette course la première fois et puis toutes les heures.

Je ne pouvais pas synchroniser et changer la vitesse de mes setIntervals aussi et j'étais sur le point de poser une question. Mais je pense que je l'ai trouvé un moyen. Il devrait certainement être amélioré parce que je suis un débutant. Donc, je lirais volontiers vos commentaires / remarques à ce sujet.

<body onload="foo()">
<div id="count1">0</div>
<div id="count2">2nd counter is stopped</div>
<button onclick="speed0()">pause</button>
<button onclick="speedx(1)">normal speed</button>
<button onclick="speedx(2)">speed x2</button>
<button onclick="speedx(4)">speed x4</button>
<button onclick="startTimer2()">Start second timer</button>
</body>
<script>
var count1 = 0,
    count2 = 0,
    greenlight = new Boolean(0), //blocks 2nd counter
    speed = 1000,   //1second
    countingSpeed;
function foo(){
    countingSpeed = setInterval(function(){
        counter1();
        counter2();
    },speed);
}
function counter1(){
    count1++;
    document.getElementById("count1").innerHTML=count1;
}
function counter2(){
    if (greenlight != false) {
        count2++;
        document.getElementById("count2").innerHTML=count2;
    }
}
function startTimer2(){
    //while the button hasn't been clicked, greenlight boolean is false
    //thus, the 2nd timer is blocked
    greenlight = true;
    counter2();
    //counter2() is greenlighted
}

//these functions modify the speed of the counters
function speed0(){
    clearInterval(countingSpeed);
}
function speedx(a){
    clearInterval(countingSpeed);
    speed=1000/a;
    foo();
}
</script>

Si vous voulez que les compteurs pour commencer à augmenter une fois que la page est chargée, mettre counter1() et counter2() dans foo() avant countingSpeed est appelée. Dans le cas contraire, il faut millisecondes speed avant l'exécution. EDIT:. Réponse Shorter

Je suis un débutant en javascript, et n'a trouvé aucune aide dans les réponses précédentes (mais beaucoup de bonnes idées).
Ce morceau de code ci-dessous accélère (accélération> 1) ou décélération (accélération <1). J'espère que cela pourrait aider certaines personnes:

function accelerate(yourfunction, timer, refresh, acceleration) {
    var new_timer = timer / acceleration;
    var refresh_init = refresh;//save this user defined value
    if (refresh < new_timer ){//avoid reseting the interval before it has produced anything.
        refresh = new_timer + 1 ;
    };
    var lastInter = setInterval(yourfunction, new_timer);
    console.log("timer:", new_timer);
    function stopLastInter() {
        clearInterval(lastInter);
        accelerate(yourfunction, new_timer, refresh_init, acceleration);
        console.log("refresh:", refresh);
    };
    setTimeout(stopLastInter, refresh);
}

  • timer: la valeur initiale setInterval en ms (croissante ou décroissante)
  • refresh: le temps avant une nouvelle valeur de timer est calculée. Ceci est la étape longueur
  • factor: l'écart entre l'ancien et la prochaine valeur timer. Ceci est la la hauteur de marche
(function variableInterval() {
    //whatever needs to be done
    interval *= 2; //deal with your interval
    setTimeout(variableInterval, interval);
    //whatever needs to be done
})();

ne peut pas obtenir une plus courte

Faire une nouvelle fonction:

// set Time interval
$("3000,18000").Multitimeout();

jQuery.fn.extend({
    Multitimeout: function () {
        var res = this.selector.split(",");
        $.each(res, function (index, val) { setTimeout(function () { 
            //...Call function
            temp();
        }, val); });
        return true;
    }
});

function temp()
{
    alert();
}

Voici une autre façon de créer une décélération / accélération intervallomètre. L'intervalle est multiplié par un facteur jusqu'à ce qu'un temps total est dépassée.

function setChangingInterval(callback, startInterval, factor, totalTime) {
    let remainingTime = totalTime;
    let interval = startInterval;

    const internalTimer = () => {
        remainingTime -= interval ;
        interval *= factor;
        if (remainingTime >= 0) {
            setTimeout(internalTimer, interval);
            callback();
        }
    };
    internalTimer();
}
var counter = 15;
var interval = setTimeout(function(){
    // your interval code here
    window.counter = dynamicValue;
    interval();
}, counter);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top