简体   繁体   中英

Conflit between setInterval and setTimeout

With an educational purpose I wrote the follow pice of code in JavaScript. The goal is to simulate a teletype machine and after the content is written the machine makes a pause before starts again.

var str = 'Some text';
strArray = str.split("");
window.onload = function teleType() {
  var ctrl = 0;
  var wrapId = document.getElementById("wrap");
  var type = setInterval(function() {
    wrapId.innerHTML += strArray[ctrl];
    if (ctrl == strArray.length) {
      wrapId.innerHTML = "";
      ctrl = 0;
      clearInterval(type);
    }
    ctrl++;
  }, 2000);
  setTimeout(teleType, 3000);
}

But with these intervals (mlliseconds) the machine begin to have an odd behavior. It jumps letters (index) or it starts from the begining without reach the end of the string (array). What is happening between the setInterval and the setTimeout ?

After setInterval is called you call setTimeout immediatelly.
As the result, you will trigger teleType before your interval completes.

You can move your setTimeout in the end of your interval:

 var str = 'Some text'; strArray = str.split(""); window.onload = function teleType() { var ctrl = 0; var wrapId = document.getElementById("wrap"); var type = setInterval(function() { wrapId.innerHTML += strArray[ctrl]; if (ctrl == strArray.length) { wrapId.innerHTML = ""; ctrl = 0; clearInterval(type); setTimeout(teleType, 300); } ctrl++; }, 200); } 
 <div id="wrap"></div> 

Now, teleType function runs interval, and when it finishes writing text it clears HTML content and tells browser to run teleType again in 2 seconds.

By the way, you don't need to set ctrl to 0, because it is local and will be reset anyway.

A sample function which outputs the text to console,

function showTeleText(text, repeat) {
    var textByChar = text.split(''),
        intermText = '',
        textPos = 0;

    var interval = setInterval(function () {
        intermText += textByChar[textPos++]
        console.log(intermText);

        if (textPos >= textByChar.length) {
            clearInterval(interval);

            if (repeat) {
                setTimeout(function () {
                    showTeleText(text, repeat);
                }, 2000);
            }
        }
    }, 500);
}

on window.load call showTeleText('Some text!', true/false) like,

window.load = function() {
    showTeleText('Some text!', true); 
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM