7

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

6

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. Commented Dec 1, 2019 at 20:47
  • @dx_over_dt - OK, I fixed that. Commented Dec 1, 2019 at 20:50
  • So if there were a lot of conditional awaits, it would produce a bunch of stringed, repeated, thens? Commented 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. Commented 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. Commented 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? Commented 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. Commented Oct 23, 2021 at 17:25

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.