4
let val = 0;

async function first() {
    console.log('1a', val);
    second();
    console.log('1b', val);
}

async function second() {
    console.log('2a', val);
    third();
    console.log('2b', val);
}

async function third() {
    console.log('3a', val);
    val = await new Promise(function (resolve, reject) {
        setTimeout(function () {
            resolve(3);
        }, 1000);
    });
    console.log('3b', val);
}

console.log('0a', val);
first();
console.log('0b', val);

I am expecting:

0a 0
1a 0
2a 0
3a 0
3b 3
2b 3
1b 3
0b 3

But I am receiving:

0a 0
1a 0
2a 0
3a 0
2b 0
1b 0
0b 0
3b 3

I'm guessing there is a fundamental thing about async which I am unaware of?

4
  • 2
    Only third is awaiting the result of a promise, all your other functions execute synchronously. Unless you await first and second, they're going to return immediately. Commented Oct 17, 2016 at 14:25
  • Well, I don't know much about await and async but surely the timeout part is basically allowing the rest of the code to finish while the await waits for the timeout to finish? (or more specifically for the Promise to finish) Commented Oct 17, 2016 at 14:25
  • Wait, what version of nodejs even supports this syntax? I've tried with v6.8.1 and it throws a syntax error. Commented Oct 17, 2016 at 14:38
  • @freakish 7 with --harmony flag node.green/#async-functions Commented Oct 17, 2016 at 14:48

2 Answers 2

4

You will have to await all async function calls:

async function first() {
    console.log('1a', val);
    await second();
    console.log('1b', val);
}

async function second() {
    console.log('2a', val);
    await third();
    console.log('2b', val);
}
Sign up to request clarification or add additional context in comments.

1 Comment

The fundamental thing I forgot was that the async returns a promise.
3

You will need to use

async function first() {
    console.log('1a', val);
    await second();
//  ^^^^^
    console.log('1b', val);
}

async function second() {
    console.log('2a', val);
    await third();
//  ^^^^^
    console.log('2b', val);
}

to chain the b logs after the asynchronous execution of the called functions.

And it's the same for

console.log('0a', val);
first();
console.log('0b', val);

only that you cannot use await here since you are not inside an aync function. Making a function async doesn't mean that it magically blocks on everything asynchronous inside it, on the contrary - its result becomes a promise that is always asynchronous, and you can use the await keyword. So to make 0b wait, you can use either

console.log('0a', val);
first().then(function() {
    console.log('0b', val);
}, function(err) {
    console.error(err);
});

or

(async function() {
    try {
        console.log('0a', val);
        first();
        console.log('0b', val);
    } catch(err) {
        console.log(err);
    }
}());

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.