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

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

I'm using the async.eachLimit function to control 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 can't declare the myFunction function as async because I don't have access to the value inside the second callback of the eachLimit function.

ベストアンサー1

You're effectively using promises inside the promise constructor executor function, so this is 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 immediatePromise コンストラクター実行関数内の例外は、新しく構築された Promise を都合よく拒否します (ただし、内部では.then独自の処理が必要です)。

2番目の方法は、関数内の即時例外がasync拒否されるため機能しません。async関数自体によって返される暗黙の約束

プロミス コンストラクター エグゼキューター関数の戻り値が未使用なので、これは悪いニュースです。

あなたのコード

myFunctionを次のように定義できない理由はありません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.
    });
  });
}

しかし、古い同時実行制御ライブラリを使用するのはなぜでしょうかawait?

おすすめ記事