1

I have a strange javascript behaviour that I cannot explain. When I run

const waitFor = (ms) => new Promise(r => setTimeout(r, ms))

// const o = 2;

[1, 2, 3].forEach(async (num) => {
  await waitFor(50);
  console.log(num);
});

console.log('Done');

It only logs Done. This is expected since forEach cannot get async callbacks.

However if you uncomment the line const o = 2 (o is not used), it logs

Done
1
2
3

Can you explain why?

rocketer
  • 1,000
  • 3
  • 10
  • 32

1 Answers1

3

The first line is missing a semicolon. Without the semicolon the code is parsed as:

const waitFor = (ms) => new Promise(r => setTimeout(r, ms))[1,2,3].forEach( ... )

You can verify it if you do:

console.log(waitFor);

which prints to console the full code, and not just the first line:

(ms) => new Promise(r => setTimeout(r, ms))

// const o = 2;

[1, 2, 3].forEach(async (num) => {
await waitFor(50);
window.runnerWindow.proxyConsole.log(num);
})

The array declaration and forEach loop are contained in the lambda and are never run.

If you try to start the lambda, for example with waitFor(6), the code would fail - we can see that here the comma is parsed as the comma operator:

TypeError: (new Promise(...))[3] is undefined
Kobi
  • 125,267
  • 41
  • 244
  • 277