ES8立即调用异步函数表达式

Dre*_*w R 16 javascript async-await ecmascript-2017

我没有看到这些构造使用太多,但我发现自己编写它们以在通常不会返回promise的函数中使用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);
    } 
  })();
});
Run Code Online (Sandbox Code Playgroud)

而不是

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);
    }
});
Run Code Online (Sandbox Code Playgroud)

要么

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);
       });
    }
  });
});
Run Code Online (Sandbox Code Playgroud)

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

Ber*_*rgi 29

这是'一件事'吗?

是.它不时出现,例如在这里.他们被称为IIAFE :-)
如果你想把重点放在箭头上,你也可以称之为IIAAFs.

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

每当你调用一个promise-returns函数并且不将结果返回到其他地方时,你自己负责这个承诺 - 这意味着你必须处理它的错误.所以模式一般应该是这样的

(async () => {
    …
})().catch(err => {
    console.error(err);
});
Run Code Online (Sandbox Code Playgroud)

如果您不想关注未处理的拒绝事件.

在这种情况下使用async/ 的最低限度是什么await

then版本相比,并不多.但是,你说" 外部lib不期望来自这个回调的返回值 ",这可能暗示库与异步回调不兼容,所以要小心你在做什么.它也可能依赖于从回调中同步抛出的异常,所以这一切都取决于库在这里期望的内容(如果没有期望,那么将来是否会发生变化).如果库将开始特别处理promise promise值,则不希望将来出现不兼容问题.

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

function toVoid(fn) {
    return (...args) => void fn(...args);
}
function promiseToVoid(fn) {
    return (...args) => void fn(...args).catch(console.error);
}
Run Code Online (Sandbox Code Playgroud)

您可以这样使用:

chan.consume(queue, toVoid(async (msg) => {
     … // use `await` freely
}));
Run Code Online (Sandbox Code Playgroud)


小智 16

(async () => {
  await func();
})();
Run Code Online (Sandbox Code Playgroud)