Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

143
Views
setTimeout in a for loop changes final output; how to delay runs of a for loop, without changing final result

I'm trying to make a custom typewriter effect on my site using a javascript function. In order to add a delay between the typing of each letter, I've implemented a staggered setTimeout for each run of the for loop, so each iteration is delayed by an extra 300ms compared to the previous one. I need special characters (' ' '<', '&gt') to be typed as single characters rather than as individual letters, so I have a few else if conditions. This produces the desired effect when setTimeout is excluded. However, adding the delay results in spelling out the individual letters of this code after printing out the whole character. How can I fix this?

function type(fullTxt, current = '') {
    for (let i = current.length, j = 0; i < fullTxt.length; i++, j++) {
         setTimeout(function() {
            if (fullTxt.substring(i, i+6) === '&nbsp;') {
                console.log(fullTxt.substring(0, i+6));
                i = i + 5;
            } else if (fullTxt.substring(i, i+4) === '&lt;') {
                console.log(fullTxt.substring(0, i+4));
                i = i + 3;
            } else if (fullTxt.substring(i, i+3) === '&gt') {
                console.log(fullTxt.substring(0, i+3));
                i = i + 2;
            } else {
                console.log(fullTxt.substring(0, i+1));
            }
            console.log(j); //included just to ensure j is counting properly
            console.log(i); //included to check progress of loop
            console.log(fullTxt.length); //included to check endpoint of for loop
         }, j * 300);
    }
}

type('hello&nbsp;');

Expected output:

// h
// 0
// 0
// 11
// he
// 1
// 1
// 11
// hel
// 2
// 2
// 11
// hell
// 3
// 3
// 11
// hello
// 4
// 4
// 11
// hello&nbsp;
// 5
// 10
// 11
about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

you can achieve this using async function

 async function type(fullTxt, current = '') {
        for (let i = current.length, j = 0; i < fullTxt.length; i++, j++) {
             await waitFor(j*300);
                if (fullTxt.substring(i, i+6) === '&nbsp;') {
                    console.log(fullTxt.substring(0, i+6));
                    i = i + 5;
                } else if (fullTxt.substring(i, i+4) === '&lt;') {
                    console.log(fullTxt.substring(0, i+4));
                    i = i + 3;
                } else if (fullTxt.substring(i, i+3) === '&gt') {
                    console.log(fullTxt.substring(0, i+3));
                    i = i + 2;
                } else {
                    console.log(fullTxt.substring(0, i+1));
                }
                console.log(j); //included just to ensure j is counting properly
                console.log(i); //included to check progress of loop
                console.log(fullTxt.length); //included to check endpoint of for loop
             }
        }
    


type('hello&nbsp;');

here is waitFor function

function waitFor(ms){
  return new Promise(resolve=> setTimeout(resolve,ms))
}
about 4 years ago · Juan Pablo Isaza Report

0

The safer now is to use async/await, calling a Promise, this way, your loop is actually waiting for the one before to complete.

Also this makes stuffs easy to write, or later modify.

Timeout set to 2000 ms for the demo.

async function type(fullTxt, current = '') {
    for (let i = current.length, j = 0; i < fullTxt.length; i++, j++) {
            await wait(2000) // Wait for 2000ms
            if (fullTxt.substring(i, i+6) === '&nbsp;') {
                console.log(fullTxt.substring(0, i+6));
                i = i + 5;
            } else if (fullTxt.substring(i, i+4) === '&lt;') {
                console.log(fullTxt.substring(0, i+4));
                i = i + 3;
            } else if (fullTxt.substring(i, i+3) === '&gt') {
                console.log(fullTxt.substring(0, i+3));
                i = i + 2;
            } else {
                console.log(fullTxt.substring(0, i+1));
            }
            console.log(j); //included just to ensure j is counting properly
            console.log(i); //included to check progress of loop
            console.log(fullTxt.length); //included to check endpoint of for loop       
    }
}

// Generic Promise function
function wait(delayInMS) {
  return new Promise((resolve) => setTimeout(resolve, delayInMS));
}

type('hello&nbsp;');

about 4 years ago · Juan Pablo Isaza Report

0

You could put the setTimeout on only the console.log rather than around the entire if statement.

function type(fullTxt, current = '') {
  for (let i = current.length, j = 0; i < fullTxt.length; i++, j++) {
    if (fullTxt.substring(i, i + 6) === '&nbsp;') {
      setTimeout(function() {
        console.log(fullTxt.substring(0, i + 6));
      }, j * 300);
      i = i + 5;
    } else if (fullTxt.substring(i, i + 4) === '&lt;') {
      setTimeout(function() {
        console.log(fullTxt.substring(0, i + 4));
      }, j * 300);
      i = i + 3;
    } else if (fullTxt.substring(i, i + 3) === '&gt') {
      setTimeout(function() {
        console.log(fullTxt.substring(0, i + 3));
      }, j * 300);
      i = i + 2;
    } else {
      setTimeout(function() {
        console.log(fullTxt.substring(0, i + 1));
      }, j * 300);
    }
    setTimeout(function() {
      console.log(j); //included just to ensure j is counting properly
      console.log(i); //included to check progress of loop
      console.log(fullTxt.length); //included to check endpoint of for loop
    }, j * 300);
  }
}

type('hello&nbsp;');

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!