1

Can someone help explain to me why is it behave this way?

To the best of my knowledge, adding the await sleep(1) line should not affect the code flow in this case. However, it does.

function sleep(time) {
  return new Promise((r) => setTimeout(r, time));
}

async function test(target) {
    const ids = { a: ['a1', 'a2'], b: ['b3', 'b4'] }[target];
    for (id of ids) {
        console.log('X.', target, id);
        // await sleep(1);
        console.log('Y.', target, id);
    }
}

test('a');
test('b');

before

after

Why?

Thanks!

Rojo
  • 2,749
  • 1
  • 13
  • 34
Tony Dinh
  • 6,668
  • 5
  • 39
  • 58
  • 1
    Can you please include both examples as [Stack Snippets](https://meta.stackoverflow.com/questions/358992/ive-been-told-to-create-a-runnable-example-with-stack-snippets-how-do-i-do) this makes it easier to debug. See [Why you shouldn't upload images of code](//meta.stackoverflow.com/q/285551) for more info – Reyno Oct 18 '21 at 12:45
  • 4
    Because you should `await test('a'); await test('b');`. You arre currently running two asynchronous operations concurrently. Besides, `id` is a global variable, so both operations reuse and overwrite the same variable at the same time. No wonder you're getting a chaotic output :) – Jeremy Thille Oct 18 '21 at 12:52
  • 1
    `for(id of` makes `id` global, make it local to your for loop using `for(const id of` – Nick Parsons Oct 18 '21 at 12:52

2 Answers2

5

Try using for (const id of ids) {. Without const or let, you're defining id on the global scope.

function sleep(time) {
  return new Promise((r) => setTimeout(r, time));
}

async function test(target) {
    const ids = { a: ['a1', 'a2'], b: ['b3', 'b4'] }[target];
    for (const id of ids) {
        console.log('X.', target, id);
        await sleep(1);
        console.log('Y.', target, id);
    }
}

test('a');
test('b');
sleepy_keita
  • 1,488
  • 4
  • 17
  • 26
  • This is great point. If it is still happening, then this can be the answer: https://stackoverflow.com/questions/23392111/console-log-async-or-sync It should never happen if console.log is sync, but that is not standardized. Seems like you've proven that console.log should be considered async. – phuctm97 Oct 18 '21 at 12:59
  • Thank you! This is exactly the problem! – Tony Dinh Oct 18 '21 at 13:18
2

You're not waiting test('a') to finish.

When test('b') is reached, test('a') is still running (because it's an async function). If you want it to finish before starting the other one use .then():

test('a').then(()=>test('b'));