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.

Hydrothermal
  • 4,851
  • 7
  • 26
  • 45
John Nada
  • 77
  • 1
  • 9

3 Answers3

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);

});
Pointy
  • 405,095
  • 59
  • 585
  • 614
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>
Keith
  • 22,005
  • 2
  • 27
  • 44
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 ##
#
Khalfella
  • 99
  • 1
  • 1