TIL: You can await a promise with callbacks.
Tags: javascript, todayilearned, typescript
Published: 2022-02-03 23:51:41

I was working on some code and saw the following:

```javascript
await somePromise
    .then(/* doing something with the resolved value*/)
    .catch(/* handling errors*/);
```

I need to admit that it took me a while to understand what was happening there.
After that moment of surprise I went to the [MDN Docs on promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) and finally understood what was going on there.
My main surprise came from the habit of either using the callback style of the async/await one, but never mixing both. To be honest when async/await became official I've seldom used the callback notation again.
So a bit of context, a ton of Promise methods return a Promise. That's what enables us to chain `.then()` calls or have something like `.then().catch().finally()`. Which of these methods returns a new Promise.
Async/Await is basically a bit of syntax sugar for deal with Promises. [Async functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) are functions that return a Promise. [Await ](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await)(in a simplified way) allows us to handle a Promise being resolved in another way without needing the `.then()` callback.

```javascript
let value = await somePromise;
// is the same as
let value;
somePromise.then((v) => value = v);
```

But as I've alluded to before, the [then](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then), [catch](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch) and [finally](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/finally) methods return each a new Promise. So, since async/await is just syntax sugar for promises, we can mix and match both notations.
Here are some examples:
```javascript
requestPromise
    .then((resp) => resp.data)
    .then((data) => updateState(data))
    .catch((err) => console.error(err))
    .finally(() =>  console.info("we're done here"));

// --------------------------
// Is the same as
// --------------------------

try {
    const resp = await requestPromise;
    await updateState(resp.data);
} catch (err) {
    console.error(err);
} finally {
    console.info("we're done here")
}

// --------------------------
// Or even
// --------------------------

// assuming only this method will throw an error.
// if it throws, resp will be undefined
const resp = await requestPromise
    .catch((err) => console.error(err));

if (resp) {
    await updateState(resp.data);
}

console.info("we're done here")

// --------------------------
// Or we can just await for the whole thing in a async function
// --------------------------

await requestPromise
    .then((resp) => resp.data)
    .then((data) => updateState(data))
    .catch((err) => console.error(err))
    .finally(() =>  console.info("we're done here"));
```

---

It's an interesting pattern that honestly I never though about until now and I found it curious. I'm not 100% sure if I will mix and match the styles like this, I think it may become a bit confusing, at least while you're not used to it.
I can see the appeal of having the catch without the try block, but again, not 100% sold on it. Probably time will tell.
So, what do you think? Is this a pattern you've seen before? Is this something that you actively use? If so, in what contexts? If not would you use this mixing pattern?