DEV Community

Arnaud
Arnaud

Posted on

Untangle async calls from the try/catch block

Promises are resolved using a then/catch block like so:

myPromise .then((data) => { // promise resolved doStuff(data); }) .catch((error) => { // promise rejected throw error; }); 

The async/await keywords came along, and handling promises became a little easier, the code above can now be written like this:

try { const data = await myPromise; // promise resolved doStuff(data); } catch (error) { // promise rejected throw error; } 

While this is arguably better, the try/catch block becomes really tiring to write after a while, so I've taken some inspiration from node to simplify this code a little bit. Node uses an idiomatic pattern called Error-first callbacks. By convention, callbacks get two parameters: the first one is the error, and the second one is the data. Our examples above also have an error and a data, so let's see how we can rewrite this:

const doAwait = async (promise) => { try { const data = await promise; return [undefined, data]; } catch (error) { return [error, undefined]; } }; 

The doAwait function takes a promise, and returns an array with two elements, the first one is the error, and the second one is the data.

Using this simple function spares developers from writing try/catch blocks over and over again, and can just destructure the returned value into an array, and handle the error in a way that is similar to how callbacks are written in node:

const [error, result] = await doAwait(myPromise); if (error) { throw error; } doStuff(result); 

I find this little function quite handy, and the npm package to-await actually does just that, and it also provides a handy utility to resolve an array of promises! Visit its README for more code examples.

Top comments (0)