0

I have an async function that might fails:

const f = () => new Promise((_, reject) => reject("Ups"));

and a FALLBACK value constant:

const FALLBACK = { name: "Raul" };

I am trying to destructure the name field from the f() method response data, (as, if it doesn't fail, the return will be an object with this field), and in case that it fails, I use the fallback value.

I am doing the following:

function f() {
  return new Promise((_, r) => r("Ups"));
}

const FALLBACK = { name: "Raul" };

(async () => {
  const { name } = (await f().catch(() => {})) ?? FALLBACK; // I need to refactor this line

  console.log(name);
})();

How can I refactor this code?

Raul
  • 2,673
  • 1
  • 15
  • 52
  • First of all use .then .catch or async await , do not mix them – Tushar Mistry Nov 17 '21 at 19:17
  • 1
    "*I need to refactor this line*" refactor it how? I'm not sure what the goal is. – VLAZ Nov 17 '21 at 19:18
  • Also, you created an [Explicit Promise Constructor Anti-Pattern](https://stackoverflow.com/questions/23803743/what-is-the-explicit-promise-construction-antipattern-and-how-do-i-avoid-it) – Randy Casburn Nov 17 '21 at 19:18
  • 1
    @RandyCasburn I think this is just an example of an async function that rejects, not the real code. – VLAZ Nov 17 '21 at 19:19
  • OP still constructed and returned a Promise from an Async function - that's a no-no. - In other words, the OP doesn't realize it - he just needs to remove the `async` key word. – Randy Casburn Nov 17 '21 at 19:19
  • 2
    Don't you just want `await f().catch(() => FALLBACK)`. If `f()` rejects, then you'll substitute the `FALLBACK` object as the result. – jfriend00 Nov 17 '21 at 19:22
  • @VLAZ - besides, if I didn't say it Bergi will be around and say it anyway. :-) – Randy Casburn Nov 17 '21 at 19:23
  • @RandyCasburn why is it an anti-pattern? I mean, I am not making an unnecessary chain of .then/.catch, just returning a promise that rejects. BTW, yeah, the async keyword wasn't necessary. – Raul Nov 17 '21 at 19:39
  • 1
    Hey Raul - the anti-pattern is unnecessarily wrapping Promise Objects inside Promise Objects. In the code you provided, you return a Promise Object from a function tagged as an Async function - which by definition forces the function to return a Promise Object. So, as you point out, the `async` keyword was not required - and it's all fixed up. – Randy Casburn Nov 17 '21 at 20:40

1 Answers1

3

It seems that you just want await f().catch(() => FALLBACK). If f() rejects, then you'll substitute the FALLBACK object as the result

Here's a working example:

function f() {
  return new Promise((_, r) => r("Ups"));
}
const FALLBACK = { name: "Raul" };

(async () => {
  const { name } = await f().catch(() => FALLBACK); 

  console.log(name);
})();

Some will not like the mixing of .catch() and await and suggest using try/catch instead of .catch(). Either will work - that's a style preference. In this particular situation, I find .catch() to be simpler looking - but follow your own preference.

Also, note that I removed the async from the f() definition. Since you're not using any of the features of an async function, it is not necessary or useful.

And, note that it is sometimes dangerous to blindly .catch() all possible errors without even logging the error. Something as simple as a typing error upstream may cause this .catch() to trigger and you will be quite confused why your code is suddenly doing what it's doing (because you're silently eating an error you probably didn't intend to eat and you should at least be logging).

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • yeah, sorry for the async keyword, in my real code I was awaiting some stuff before returning, just copied and paste. – Raul Nov 17 '21 at 19:33