45

これらのコンストラクトがあまり使用されているのを見たことはありませんが、通常はプロミスを返さない関数で async / await を使用するためにそれらを作成していることに気付きました。たとえば、

chan.consume(queue, (msg) => {
  this.pendingMsgs++; // executed immediately
  (async () => {
    await this.handleMessage(msg);
    this.pendingMsgs--;
    if (cancelled && this.pendingMsgs === 0) {
       await chan.close();
       await this.amqpConnectionPool.release(conn);
    } 
  })();
});

とは対照的に

chan.consume(queue, async (msg) => { // external lib does not expect a return value from this callback
  this.pendingMsgs++;  // executed in promise context(?)
  await this.handleMessage(msg);
  this.pendingMsgs--;
    if (cancelled && this.pendingMsgs === 0) {
       await chan.close();
       await this.amqpConnectionPool.release(conn);
    }
});

また

chan.consume(queue, (msg) => {
  this.pendingMsgs++;  // no await - excess function decls & nesting
  this.handleMessage(msg).then(() => {
    this.pendingMsgs--;
    if (cancelled && this.pendingMsgs === 0) {
       chan.close().then(() => {
         this.amqpConnectionPool.release(conn);
       });
    }
  });
});

これは「もの」ですか?ここに注意すべき落とし穴はありますか?この種の状況での async / await の使用に関するローダウンは何ですか?

4

2 に答える 2

63

これは「もの」ですか?

はい。それは時々出てきます、例えばhere。それらは IIAFE として知られています :-)
矢印に焦点を合わせたい場合は、IIAAF と呼ぶこともできます。

ここに注意すべき落とし穴はありますか?

promise を返す関数を呼び出し、結果を別の場所に返さない場合は常に、promise の責任は自分にあります。つまり、promise からのエラーを処理する必要があります。したがって、パターンは一般的に次のようになります

(async () => {
    …
})().catch(err => {
    console.error(err);
});

未処理の拒否イベントを心配したくない場合。

この種の状況でasync/を使用する際のローダウンは何ですか?await

thenバージョンに比べて、それほど多くはありません。ただし、「外部ライブラリはこのコールバックからの戻り値を期待していません」と言います。これは、ライブラリが非同期コールバックと互換性がないことを示唆している可能性があるため、いつ何をしているのか注意してください。また、コールバックから同期的にスローされる例外にも依存する可能性があるため、ライブラリがここで何を期待しているかに依存します (期待がない場合は、将来変更される可能性があるかどうか)。ライブラリが promise の戻り値を特別に扱い始める場合に備えて、将来の非互換性は望ましくありません。

asyncただし、可読性が高いため、コールバックとして関数を直接渡す 2 番目のパターンを引き続きお勧めします。promise をライブラリに返さないようにしたい場合は、コールバックをラップするヘルパー関数を作成します。

function toVoid(fn) {
    return (...args) => void fn(...args);
}
function promiseToVoid(fn) {
    return (...args) => void fn(...args).catch(console.error);
}

次のように使用できます。

chan.consume(queue, toVoid(async (msg) => {
     … // use `await` freely
}));
于 2016-11-22T16:10:59.740 に答える