ES8立即调用异步函数表达式 [英] ES8 Immediately invoked async function expression

查看:108
本文介绍了ES8立即调用异步函数表达式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我没有看到这些构造使用太多,但是我发现自己编写它们以在通常不会返回承诺的函数中使用async/await

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

相对于

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

这是东西"吗?我应该注意这里的陷阱吗? 在这种情况下使用异步/等待的低端是什么?

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?

推荐答案

这是东西"吗?

Is this 'a thing'?

是的.它不时出现,例如此处.它们被称为IIAFE :-)
如果您想将焦点放在箭头上,也可以将其称为IIAAF.

Yes. It comes up every now and then, e.g. here. They're known as IIAFEs :-)
If you want to put focus on the arrow, you could also call them IIAAFs.

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

Are there pitfalls here I should be aware of?

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

Whenever you call a promise-returning function and don't return the result to somewhere else, you are responsible for the promise yourself - which means that you have to handle errors from it. So the pattern should in general look like

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

如果您不想让自己担心未处理的拒绝事件.

if you don't want to concern yourself with unhandled-rejection events.

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

then版本相比,

并不多.但是,您说"外部库不希望该回调返回值",这可能暗示该库与异步回调不兼容,因此请当心您在做什么.这也可能取决于从回调同步引发的异常,因此,这完全取决于库在这里的期望(如果没有期望,将来是否会改变).您不希望将来出现不兼容的情况,以防库将开始特别处理promise返回值.

Not much, compared to the then version. However, you say "the external lib does not expect a return value from this callback", which might hint at the library's incompatibility with asynchronous callbacks, so beware what you are doing when. It also might depend on exceptions being thrown synchronously from the callback, so it all depends on what the library expects here (and if there are no expectations, whether that may change in the future). You don't want future incompatibilities in case the library will start to treat promise return values specially.

但是,我仍然建议直接使用async函数作为回调的第二种模式,因为它具有更好的可读性.如果您想避免将诺言返回给库,请创建一个包装回调的帮助器函数:

However, I would still recommend the second pattern that directly passes the async function directly as the callback because of its better readability. If you want to avoid returning a promise to the library, create a helper function that wraps the callback:

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

这篇关于ES8立即调用异步函数表达式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆