Is it an anti-pattern to use async/await inside of a new Promise() constructor?

后端 未结 3 882
夕颜
夕颜 2020-11-22 00:28

I\'m using the async.eachLimit function to control the maximum number of operations at a time.

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

functi         


        
3条回答
  •  北恋
    北恋 (楼主)
    2020-11-22 01:15

    You're effectively using promises inside the promise constructor executor function, so this the Promise constructor anti-pattern.

    Your code is a good example of the main risk: not propagating all errors safely. Read why there.

    In addition, the use of async/await can make the same traps even more surprising. Compare:

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

    with a naive (wrong) async equivalent:

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

    Look in your browser's web console for the last one.

    The first one works because any immediate exception in a Promise constructor executor function conveniently rejects the newly constructed promise (but inside any .then you're on your own).

    The second one doesn't work because any immediate exception in an async function rejects the implicit promise returned by the async function itself.

    Since the return value of a promise constructor executor function is unused, that's bad news!

    Your code

    There's no reason you can't define myFunction as 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 outdated concurrency control libraries when you have await?

提交回复
热议问题