how to add delay in javascript

Tags: ,



function abc(elm){
    this.$elm =  document.querySelector(elm)
}

abc.prototype.addClass =  function (str){
  this.$elm.classList.add(str)
    return this
}

abc.prototype.removeClass =  function (str){
   this.$elm.classList.remove(str)
    return this
}

abc.prototype.delay =  function (timer){
   let self = this
  
  setTimeout(()=>{
    return self
  },timer)
    return this
}

function $(str){
  return new abc(str);
}

let x = $('#test').delay(5000).delay(1000).addClass('red');

console.log($('#test'));

I want to add red class after 6 secs.I tried like using setTimeout but not work.could you please suggest the better way ?

I want to write a delay function which delay for sometime before proceeding/executing next code.

Answer

You can make a very simple queue of tasks to be executed based off promises. Since the promise execution already uses a task queue, you just need to keep a single promise and any time you get a new thing to add, you chain it via .then() and keep the latest promise. That way if you add three tasks T1 -> T2 -> T3, they would resolve in the order they were added. If you add a task that just adds a simple delay between them like T1 -> wait 6 seconds -> T2 -> wait 5 seconds -> T3 then that will run also space out the executions.

This is a sample implementation to illustrate the idea that utilises thunks (functions that take no parameters) as task to delay and execute later.

function abc(elm){
    this.$elm =  document.querySelector(elm)
    this.queue = Promise.resolve();
}

/**
 * Uniform way of adding a task for later execution
 * @param {Function} task - a thunk to be executed later
 * @param {number} [delay=0] time in milliseconds to wait after last task finished before executing this on
 */
abc.prototype.addTask = function(task, delay = 0) {
  const waitFor = () => new Promise( res => setTimeout(res, delay) );
  
  this.queue = this.queue
        .then(waitFor)
        .then(task)
}

abc.prototype.addClass =  function (str){
  this.addTask(() => this.$elm.classList.add(str));
  return this
}

abc.prototype.removeClass =  function (str){
  this.addTask(() => this.$elm.classList.remove(str));
  return this
}

abc.prototype.delay =  function (timer){
  // add an empty function as a task. If needed this can also do logging or other internal logic
  this.addTask(() => {}, timer);
  return this
}

function $(str){
  return new abc(str);
}

//usage

let x = $('#test').delay(5000).delay(1000).addClass('red');

x.delay(1000)
  .delay(1000)
  .delay(1000)
  .delay(1000)
  .delay(1000) //5 seconds
  .removeClass('red');
.red {
  background-color: red;
  color: white;
}
<p id="test">
Bacon ipsum dolor amet hamburger t-bone pork, pastrami sirloin swine corned beef tenderloin frankfurter tail ball tip meatball pork belly spare ribs prosciutto. Bresaola turkey buffalo jowl t-bone biltong burgdoggen cow capicola meatball pastrami boudin alcatra. Bresaola chicken bacon cow, frankfurter meatball hamburger jerky. Shankle capicola chicken leberkas turkey. Ball tip bacon doner kielbasa jerky. Salami picanha chicken bacon, turducken buffalo chislic andouille porchetta tongue shankle prosciutto t-bone. Beef andouille cow pork chop alcatra, turducken ribeye sirloin tail boudin strip steak doner.
</p>


Source: stackoverflow