2

I am trying to change text so that they happen one at a time, almost in a consecutive looking way.

columns.forEach((x) => { setTimeout(() => { x.style.color="red" }, 2500) }) 

However, this is just delaying them all from happening 2500ms and then after 2500ms, they all change at the same time.

4
  • 1
    Replace (x) with (x, i) (that's the index) and set the delay to something like 2500 + i * 500 Commented Jan 14, 2019 at 23:55
  • 2
    A queue would be so much better Commented Jan 14, 2019 at 23:55
  • I'd probably use a queue too but to be honest this internally is essentially a queue anyway. Commented Jan 14, 2019 at 23:56
  • You can use promises: stackoverflow.com/questions/43082934/… Commented Jan 14, 2019 at 23:57

3 Answers 3

4

The .forEach() method passes the index value as the second argument. You can multiply that by some constant to spread out the timers:

columns.forEach((x, index) => { setTimeout(() => { x.style.color="red"; }, 2500 + index * 500); }); 
Sign up to request clarification or add additional context in comments.

4 Comments

Shouldn't the delay be (index + 1) * 2500?
@ibrahimmahrir Why do you figure OP wants 2500 between each?
@ChrisG OP is using 2500 in his setTimeout.
It can be whatever the OP wants; it's just an example.
2

Promises with async / await, make doing things like this looks so much more natural, and easy to follow / debug.

const columns = document.querySelectorAll("td"); const sleep = (ms) => new Promise(r => setTimeout(r, ms)); async function run() { for (const c of columns) { await sleep(2500); c.style.color = 'red'; } } run();
td { border: 1px solid black; padding: 5px; margin: 3px; }
<table> <tr> <td>1</td> <td>2</td> <td>3</td> <td>4</td> <td>5</td> <td>6</td> <td>7</td> </tr> </table>

Comments

0

How about something like this?

# cat forEachAsync.js function forEachAsync(array, fun, cb) { var index = 0; if (index == array.length) { cb(null); return; } var next = function () { fun(array[index], function(err) { if (err) { cb(err); return; } index++; if (index < array.length) { setImmediate(next); return; } //We are done cb(null); }); }; next(); } var columns = [1,2,3,4,5] forEachAsync(columns, function(e, cb) { console.log('changing column: ' + e); // let them know we have done with this // entry so we can start processin the // next entry. cb(); }, function(err) { if (err) { console.log('Failed in the process' + e.toString()); return; } console.log('## done ##'); }); # node forEachAsync.js changing column: 1 changing column: 2 changing column: 3 changing column: 4 changing column: 5 ## done ## # 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.