Is this an anti-pattern for using async / await inside the new Promise () constructor?

I use a function async.eachLimit

to manage the maximum number of operations at a time.

const { eachLimit } = require("async");

function myFunction() {
 return new Promise(async (resolve, reject) => {
   eachLimit((await getAsyncArray), 500, (item, callback) => {
     // do other things that use native promises.
   }, (error) => {
     if (error) return reject(error);
     // resolve here passing the next value.
   });
 });
}

      

As you can see, I cannot declare the function myFunction

as async because I have no access to the value in the second callback of the function eachLimit

.

+19


source to share


1 answer


You are effectively using promises inside a promise constructor executor function, so this is the anti-pattern of the Promise pattern .

Your code is a good example of a basic risk: Don't propagate all bugs safely. Read why there .

Also, using async

/ await

can make some more surprises. For comparison:

let p = new Promise(resolve => {
  ""(); // TypeError
  resolve();
});

(async () => {
  await p;
})().catch(e => console.log("Caught: " + e)); // Catches it.
      

Run codeHide result


with a naive (wrong) equivalent async

:

let p = new Promise(async resolve => {
  ""(); // TypeError
  resolve();
});

(async () => {
  await p;
})().catch(e => console.log("Caught: " + e)); // Doesn't catch it!
      

Run codeHide result




Look in your browser for the web console for the latter.

The first one works because any immediate exception in the executor function of the Promise constructor conveniently rejects the newly constructed promise (but inside any, .then

you're on your own).

The second doesn't work because any immediate exception in the function async

rejects the implicit promise returned by the function itself async

.

Since the return value of the promise executor function is not used, this is bad news!

Your code

There is no reason why you cannot define myFunction

how async

:

async function myFunction() {
  let array = await getAsyncArray();
  return new Promise((resolve, reject) => {
    eachLimit(array, 500, (item, callback) => {
      // do other things that use native promises.
    }, error => {
      if (error) return reject(error);
      // resolve here passing the next value.
    });
  });
}

      

Though why use legacy concurrency management libraries when you have one await

?

+21


source







All Articles