45

I haven't seen these constructs used much but I've found myself writing them to make use of async / await in functions that wouldn't typically return a promise, for example

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);
    } 
  })();
});

as opposed to

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);
    }
});

or

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);
       });
    }
  });
});

Is this 'a thing'? Are there pitfalls here I should be aware of? What's the lowdown on use of async / await in these kind of situations?

4

2 回答 2

63

这是“一件事”吗?

是的。它时不时出现,例如here。它们被称为 IIAFEs :-)
如果你想把注意力放在箭头上,你也可以称它们为 IIAAFs。

这里有我应该注意的陷阱吗?

每当您调用一个返回承诺的函数并且不将结果返回到其他地方时,您自己对承诺负责 - 这意味着您必须处理来自它的错误。所以模式通常应该看起来像

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

如果您不想担心未处理的拒绝事件。

在这种情况下使用async/有什么不足之处?await

不多,与then版本相比。但是,您说“外部库不期望此回调的返回值”,这可能暗示该库与异步回调不兼容,因此请注意您何时执行的操作。它还可能取决于从回调同步抛出的异常,所以这完全取决于库在这里的期望(如果没有期望,将来是否会改变)。您不希望将来出现不兼容性,以防库开始特别处理承诺返回值。

但是,我仍然推荐第二种直接将async函数直接作为回调传递的模式,因为它具有更好的可读性。如果您想避免向库返回承诺,请创建一个包装回调的辅助函数:

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 回答
5
(async () => {
        await func();
    })();
于 2021-03-30T13:37:10.643 回答