2

Asynchronous JS has always been a bit confusing for me...

I have this example code:

function asyncFunction() {
    return new Promise(function(resolve, reject) {
        resolve([1, 2, 3, 4, 5])
    })
};

function example() {
    asyncFunction().then(
        output => {
            for (element of output) {
                console.log(element + ", A") //This should be displayed first
            }
        }
    )
};

example();

console.log('B'); //But it isn't

Which produces the following output:

B
1, A
2, A
3, A
4, A
5, A

Is there a way to program this so that B will be printed after the As? I'm actually using an RSS feed parser module here, the above is just an example to illustrate the problem.

1
  • console.log('B'); would need to be included in the then function because non-async code will always be executed before async code. Commented Oct 7, 2020 at 1:03

1 Answer 1

5

Calling asyncFunction returns a Promise. Even if the Promise resolves immediately, any .thens chained onto it will be put into the microtask queue, whose tasks will only start running once all other synchronous code has finished.

Since console.log('B'); runs synchronously after the example call, B will be printed before the .then callback runs.

If you want to be sure B gets logged after all array elements are logged, return the asyncFunction promise from example, then call .then on it, and log B inside that .then's callback:

function asyncFunction() {
    return new Promise(function(resolve, reject) {
        resolve([1, 2, 3, 4, 5])
    })
};

function example() {
    return asyncFunction().then(
        output => {
            for (element of output) {
                console.log(element + ", A") //This should be displayed first
            }
        }
    )
};

example().then(() => {
  console.log('B'); //But it isn't
});

Sign up to request clarification or add additional context in comments.

6 Comments

It's described in HostEnqueuePromiseJob, which basically says: "run this function at some future time".
developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/… — “To avoid surprises, functions passed to then() will never be called synchronously, even with an already-resolved promise..”
I forgot to mention this, but there's an additional complicating factor with this.
@Tee1er What is the complicating factor?
@Tee1er Use Promise.all instead: Promise.all(output.map(parseElement)).then(mainProgram) where parseElement returns the asynchronous parsing
|

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.