# JavaScript help - looping with delay

**URL:** <https://forum.freecodecamp.org/t/javascript-help-looping-with-delay/332667>\
**Category:** General\
**Created:** [December 12, 2019, 8:18am UTC](https://forum.freecodecamp.org/t/javascript-help-looping-with-delay/332667 "2019-12-12T08:18:34Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![sgedye](https://sea3.discourse-cdn.com/freecodecamp/user_avatar/forum.freecodecamp.org/sgedye/32/127981_2.png) [@sgedye](https://forum.freecodecamp.org/u/sgedye)\
**Post date:** [December 12, 2019, 8:18am UTC](https://forum.freecodecamp.org/t/javascript-help-looping-with-delay/332667/1 "2019-12-12T08:18:35Z")

</div>

Hi guys and gals,

I wonder if you would be able to help me. I have a function that removes all items in a cart, the code (while loop) works, but I want to remove one at a time, with a visible delay (say 200ms).

It looks like an IIFE would be the way to go with a setTimeout function, but I can’t get it to work. Any ideas? – N.B. My failed attempts are commented out.

Any help is greatly appreciated. Thanks 🙂

```auto
removeAll() {
    // This works!
    while (this.cart.childElementCount > 2) {
      this.cart.removeChild(this.cart.children[0]);
    }
    /* ***: Failed Attempts - These don't work :***
    // Attempt #1
    while (this.cart.childElementCount > 2) {
      (() => { 
        setTimeout(() => {
          this.cart.removeChild(this.cart.children[0]);
        },200);
      })();
    }
    ***************************
    // Attempt #2
    (function removeFirst() {
      if (this.cart.childElementCount > 2) {
        setTimeout(() => { this.cart.removeChild(this.cart.children[0]); }, 200);
        removeFirst();
      }
    })(); *** */
  }

```

---

<div class="post-metadata">

**Author:** ![Marmiz](https://sea3.discourse-cdn.com/freecodecamp/user_avatar/forum.freecodecamp.org/marmiz/32/74845_2.png) [@Marmiz](https://forum.freecodecamp.org/u/Marmiz)\
**Post date:** [December 12, 2019, 8:46am UTC](https://forum.freecodecamp.org/t/javascript-help-looping-with-delay/332667/2 "2019-12-12T08:46:51Z")

</div>

Is there any particular technical reason you want it to be delayed, besides the visual aspect?

I say so since JS is by nature a synchronous language and manually force async generally involves some tweaking.

The easiest approach would be increasing the timeout based on a loop condition (usually index)

```auto
for(let i = 0; i < 3; i++) {
 setTimeout(myFunc, i *10)
}

// the program generates a stack of 3 function delayed by 0, 10, 20 ms

```

A more robust approach would probably involve wrapping the delete function inside a `Promise` and then call each only after the previous Promise resolve.  
This will easily lead to the so called callback-hell.

However if the reasoning behind this is purely visual, you don’t really need to turn a sync function into an async one, you can simply use a `delayed css animation` to give the “impression” of a _one by one_ action.

Hope this helps 👍

---

<div class="post-metadata">

**Author:** ![pjonp](https://sea3.discourse-cdn.com/freecodecamp/user_avatar/forum.freecodecamp.org/pjonp/32/131704_2.png) [@pjonp](https://forum.freecodecamp.org/u/pjonp)\
**Post date:** [December 12, 2019, 9:04am UTC](https://forum.freecodecamp.org/t/javascript-help-looping-with-delay/332667/3 "2019-12-12T09:04:01Z")

</div>

I actually just had this issue a hour back…

Basically, what I found was that `this` is cleared from memory before the timeout function runs.

Not sure if it would work in you situation with the loop (over even if it’s good practice), but:

```auto
    while (this.cart.childElementCount > 2) {
      (() => { 

let tempCart = this.cart
 
        setTimeout(() => {
          tempCart.removeChild(tempCart.children[0]);
        },200);
      })();
    }

```

---

<div class="post-metadata">

**Author:** ![Marmiz](https://sea3.discourse-cdn.com/freecodecamp/user_avatar/forum.freecodecamp.org/marmiz/32/74845_2.png) [@Marmiz](https://forum.freecodecamp.org/u/Marmiz)\
**Post date:** [December 12, 2019, 11:16am UTC](https://forum.freecodecamp.org/t/javascript-help-looping-with-delay/332667/4 "2019-12-12T11:16:01Z")

</div>

Be aware guys, that if you go for that approach you are not really creating a _one by one_ effect, but rather a _delayed_ effect.

Since all the setTimeout have the same delay, what will happen is that all those function will resolve at once after the given time.

You can see it by increasing the delay time to some seconds and logging some string in the console (or using other console method).

---

<div class="post-metadata">

**Author:** ![pjonp](https://sea3.discourse-cdn.com/freecodecamp/user_avatar/forum.freecodecamp.org/pjonp/32/131704_2.png) [@pjonp](https://forum.freecodecamp.org/u/pjonp)\
**Post date:** [December 12, 2019, 11:59am UTC](https://forum.freecodecamp.org/t/javascript-help-looping-with-delay/332667/5 "2019-12-12T11:59:25Z")

</div>

Ah yes. You are correct, didn’t think about that. The loop will run quickly and start all the “Timeouts” at the same time (basically)

My issue didn’t have a loop, just a click event with ‘cooldown’ and “this” was removed from memory before callback could run.

You are right that the delay would need to increase with each iteration to get them to remove uniformly.

@sgedye let us know how it turns out and post a CodePen if possible, Happy Coding!

---

<div class="post-metadata">

**Author:** ![sgedye](https://sea3.discourse-cdn.com/freecodecamp/user_avatar/forum.freecodecamp.org/sgedye/32/127981_2.png) [@sgedye](https://forum.freecodecamp.org/u/sgedye)\
**Post date:** [December 13, 2019, 3:31am UTC](https://forum.freecodecamp.org/t/javascript-help-looping-with-delay/332667/6 "2019-12-13T03:31:56Z")

</div>

Thanks for you comments, and yes, it was just for the visual aspect. However, ideally I would have wanted the sub-total to update. I couldn’t get the delayed css animation to work, so I did the delay using javascript. I probably could have done it with promises, but that would have added complexity.

I ended up at an acceptable solution using two loops and timeouts (one to add a css class and the other to remove the element). You can see the project [here](https://sgedye.github.io/grandmas-sweets/) (note, this project was originally forked from _john-smilga_).

Here is the function:

```auto
removeAll() {
    let numItems = this.cart.childElementCount-2; /* Minus two because the buttons are elements too */
    for (let i = 0; i<numItems; i++) {
      setTimeout(() => { this.cart.children[i].classList.add('empty-cart'); }, i*50)
    }
    setTimeout(() => {
      while (this.cart.childElementCount > 2) {
        this.cart.removeChild(this.cart.children[0]);
      }
      showTotals();
      this.showCart();
    }, numItems * 50);
  }

```

and CSS:

```auto
.empty-cart {
  display: none !important;
}

```

---

<div class="post-metadata">

**Author:** ![ILM](https://sea3.discourse-cdn.com/freecodecamp/user_avatar/forum.freecodecamp.org/ilm/32/363239_2.png) [@ILM](https://forum.freecodecamp.org/u/ILM)\
**Post date:** [January 16, 2021, 11:30am UTC](https://forum.freecodecamp.org/t/javascript-help-looping-with-delay/332667/7 "2021-01-16T11:30:36Z")

</div>

Closed on January 16, 2021, 11:30am UTC


