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

查看:32
本文介绍了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);
       });
    }
  });
});

这是一件事"吗?这里有我应该注意的陷阱吗?在这种情况下使用 async/await 的缺点是什么?

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 :-)
如果你想把注意力集中在箭头上,你也可以称之为 IIAAFs.

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 的缺点是什么?

What's the lowdown on use of async/await in these kind of situations?

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天全站免登陆