0

I'm trying to create a delay between every loop. However I'm always ending up with only with delay before loop is being fired. Way i was doing it was the following:

    for (var i = 0; i < items.length; i++)
    {
      setTimeout(function()
      {
        console.log(i + ". " + items[i]['name']);
        priceManagement.FindPrices(items[i]['name']);
      }, 3000);
    }

2 Answers2

2

Your main loop is executing setTimeout functions continuously. Due to the async nature of this function, you will expect to see the function being executed without delay between them.

You can use setInterval if you want approximate effect, when the executing time of the function is much less than the delay time. This will achieve the same with Adam's anwer.

But for the exact "create a delay between every loop", you will need some call backs.

First come in mind:

function main() {
  doWork(items, 0, items.length);
}

function doWork(items, i, loopLength) {
  // The bit in the loop
  console.log(i + ". " + items[i]['name']);
  priceManagement.FindPrices(items[i]['name']);
  i++;

  if (i < loopLength) {
    delayDoWork(items, i, loopLength);
  }
  else {
    // Do rest in the main
    ...
  }
}

function delayDoWork(items, i, loopLength) {
  setTimeout(function(items, i, loopLength)
  {
    doWork(items, i, loopLength);
  }, 3000, items, i, loopLength);
}

This will guarantee the exact delay between loops.

EDIT

You may want to do more experiment for this, as I'm not an expert knowing how setInterval is designed to work in JS, as it's not multi threading in nature? Start point will be considering the quote below from this SO

In actuality, setTimeout() re-queues the new JavaScript at the end of the execution queue.

Community
  • 1
  • 1
zc246
  • 1,514
  • 16
  • 28
  • right, that's another way, and I was aware of this. However it requires more code, and I was curious why this isn't working as I expected it to, as in different programming languages I've never had similar problem. Thank you for your explanation! – Patryk Cieszkowski Jan 29 '16 at 10:52
  • 1
    I'm not a complete JS guy either. Cheers :) – zc246 Jan 29 '16 at 10:54
1

You can do this:

 for (var i = 0; i < items.length; i++)
    {
      setTimeout(function(i)
      {
        console.log(i + ". " + items[i]['name']);
        priceManagement.FindPrices(items[i]['name']);
      }, 3000*i, i);
    }

Or can pass the items[i]['name'] as a parameter as well:

 for (var i = 0; i < items.length; i++)
    {
      setTimeout(function(i, name)
      {
        console.log(i + ". " + name);
        priceManagement.FindPrices(name);
      }, 3000*i, i, items[i]['name']);
    }

And I recommend you to read this: http://javascriptissexy.com/understand-javascript-closures-with-ease/

Adam
  • 4,985
  • 2
  • 29
  • 61