5

I'm curious how the async/await syntax is converted to Promises. Maybe I'm just not thinking about it properly, but I don't know how this code would be converted to a Promise:

async function myFunc(doAwait) {
    doSomething();
    if (doAwait) {
        await doSomethingAsync();
    }

    return doSomethingElse();
}

When doAwait is false, I'd expect this function to run equivalent to:

return new Promise(res => {
    doSomething();
    res(doSomethingElse());
});

If it's true, it would be:

return new Promise(() => { doSomething(); })
    .then(() => doSomethingAsync())
    .then(() => doSomethingElse());

It could do something like:

let p = new Promise(() => { doSomething(); });
if (doAwait) {
    p = p.then(() => doSomethingAsync());
}
return p.then(() => doSomethingElse());

But that introduces an extra, possibly unnecessary then. Maybe that's just unavoidable.

2 Answers 2

5

This async/await code:

async function myFunc(doAwait) {
    doSomething();
    if (doAwait) {
        await doSomethingAsync();
    }

    return doSomethingElse();
}

Would be basically equivalent to this:

function myFunc(doAwait) {
    doSomething();
    if (doAwait) {
        return Promise.resolve(doSomethingAsync()).then(doSomethingElse);
    }

    return Promise.resolve(doSomethingElse());
}

For complete equivalence, including synchronous exceptions in any of the functions calls, it would be something like this:

function myFunc(doAwait) {
    try {
        doSomething();
        if (doAwait) {
            return Promise.resolve(doSomethingAsync()).then(doSomethingElse);
        }

        return Promise.resolve(doSomethingElse());
    } catch(e) {
        return Promise.reject(e);
    }
}
8
  • When doAwait is true, I don't return the value of doSomethingAsync.
    – dx_over_dt
    Dec 1, 2019 at 20:47
  • @dx_over_dt - OK, I fixed that.
    – jfriend00
    Dec 1, 2019 at 20:50
  • So if there were a lot of conditional awaits, it would produce a bunch of stringed, repeated, thens?
    – dx_over_dt
    Dec 1, 2019 at 20:51
  • 1
    Well, the engine has await functionality built in. It literally suspends execution of the function body until the promise resolves/rejects. It doesn't have to rewrite code into .then() handlers.
    – jfriend00
    Dec 1, 2019 at 20:58
  • 1
    It doesn't need to transform it into regular .then() code because it can directly suspend function execution. How exactly a given engine does this is implementation dependent. It's certainly cleaner if they natively support suspending function execution upon an await without rewriting the logic.
    – jfriend00
    Dec 1, 2019 at 21:08
0

An async function has to return a promise. So to start with you may consider your;

async function af(x){
        ...
        return y;
      }

rephrased as

function af(x){
  return new Promise(v => ( ...
                          , v(y)
                          )
                    );
}

However once you do this you don't really need a try and catch stage at all since Promises natively handle that.

Please check the following at the dev tools for af(true,1000), af(true,0), af(false,1000) and af(false,0);

function boom(){
  throw "Boom..!";
}

function doStgSync(b){
  b ? console.log("Did something sycnronous..!")
    : boom();
}

function doAsyncIn(n){
  return new Promise((v,x) => n ? setTimeout( v
                                            , n
                                            , `Async operation done in ${n}ms`
                                            )
                                : x("ZERO ZERO BANG BANG..!")
                    );
}

function af(b,n){
  return new Promise(v => ( doStgSync(b)
                          , v(doAsyncIn(n))
                          )
                    );
}

af(true,1000).then(console.log)
             .catch(e => console.log(`Got error: ${e}`));
2
  • I'm not sure I follow. Can you convert my example async function into a Promise chain?
    – dx_over_dt
    Oct 23, 2021 at 17:15
  • @dx_over_dt It is basically the same code. The synchronous doSomething function in your code is doStgSync(b) function in my code. If it's argument b is true it just works or throws an error if it is false. Your doSomethingAsync function is doAsyncIn(n) in my code. If n argument is 0 then it rejects or if not takes that many ms to resolve.
    – Redu
    Oct 23, 2021 at 17:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.