0

I have the following code and I would like to execute the async functions sequentially. However, each function has different arguments. I am not sure how to cleanly achieve this unless I am using a function closure.

  const funcs = [
     func1(config, obj1, obj2, 1),
     func2(config, obj2),
     func3(config, 1),
  ];

  for (const fn of funcs) {
    try {
       await fn();
    } catch (error) {
      console.error(error)
    }
  }

I was thinking of changing the array to

  const funcs = [
     () => func1(config, obj1, obj2, 1),
     () => func2(config, obj2),
     () => func3(config, 1),
  ];
Decrypter
  • 2,784
  • 12
  • 38
  • 57
  • `Promise.all` is solution – Wang Liang Aug 06 '21 at 15:31
  • 1
    Yes, function closures is the correct way to do it. – Barmar Aug 06 '21 at 15:32
  • Does this answer your question? [How to return many Promises and wait for them all before doing other stuff](https://stackoverflow.com/questions/31426740/how-to-return-many-promises-and-wait-for-them-all-before-doing-other-stuff) – Wang Liang Aug 06 '21 at 15:32
  • 1
    @MERN That's not related to the problem. – Barmar Aug 06 '21 at 15:32
  • The problem isn't with the promises, the problem is that the functions are being called when the `funcs` array is initialized. – Barmar Aug 06 '21 at 15:33
  • @MERN The ordering is very important so Promise all won't work – Decrypter Aug 06 '21 at 15:37
  • I assume there's a reason you don't want to do `try { await func1(config, obj1, obj2, 1); await func2(config, obj2); await func3(config, 1); } catch ...`? If so, wrapping in closures is a good approach. – edemaine Aug 06 '21 at 15:39
  • I think the second way you do is the proper way. Then you use the `for of` in the first example. – ikhvjs Aug 06 '21 at 16:03

1 Answers1

4

Your solution makes perfect sense. Instead of creating an array with results, you create an array with functions that gets called in sequence.

Do you really want to ignore errors and move on if sequence is important? I would guess no. Don't blindly eat up errors. I moved the catch clause here 1 level up, but you may also consider not using a catch clause.

const funcs = [
  () => func1(config, obj1, obj2, 1),
  () => func2(config, obj2),
  () => func3(config, 1),
];

try {

  for (const fn of funcs) {
    await fn();
  }

} catch (err) {
  console.error(error)
}

But you can of course simplify this by just doing away with the array:

try {

 await func1(config, obj1, obj2, 1);
 await func2(config, obj2);
 await func3(config, 1);

} catch (err) {
  console.error(error)
}

This is way cleaner and the same thing. It seems weird to me to create a feature that 'executes several functions in sequence', because in JavaScript lines of code already run in sequence, it doesn't really need an abstraction.

Evert
  • 93,428
  • 18
  • 118
  • 189
  • Thanks for the answer and confirmation. In this case, I need to swallow the error and send it to our reporting tool. Also I don't want the other functions to fail if one before it fails – Decrypter Aug 06 '21 at 19:46
  • @Decrypter, if that's the case , you can wrap a try catch inside in the `for of` and if error ,you can catch it and `continue` instead. `for (const fn of funcs) { try { await fn(); } catch (err) { console.log(err); continue; } }` – ikhvjs Aug 09 '21 at 07:30