我还没有看到这些构造被大量使用,但我发现自己编写它们是为了在通常不会返回承诺的函数中使用 async / wait ,例如
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);
}
});
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);
});
}
});
});
这是‘一件事’吗?这里有我应该注意的陷阱吗?
在这种情况下使用 async/await 的内幕是什么?
这是‘一件事’吗?
是的。它时不时地出现,例如here。他们被称为 IIAFE :-)
如果你想把焦点放在箭头上,你也可以称它们为 IIAAF。
这里有我应该注意的陷阱吗?
每当您调用承诺返回函数并且不将结果返回到其他地方时,您就自己对承诺负责 - 这意味着您必须处理其中的错误。所以模式一般应该是这样的
(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
}));
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)