当前位置: 首页 > 知识库问答 >
问题:

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

宁浩博
2023-03-14

我没有看到这些构造使用很多,但我发现自己编写它们是为了在通常不会返回promise的函数中使用异步/等待

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/wait的原因是什么?

共有2个答案

闻飞跃
2023-03-14
(async () => {
        await func();
    })();
江育
2023-03-14

这是一件事吗?

对它不时出现,例如这里。它们被称为IIAFE:-)
如果你想把注意力集中在箭头上,你也可以称它们为IIAFS。

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

无论何时调用promise返回函数而不将结果返回到其他地方,您都要自己对promise负责,这意味着您必须处理来自promise的错误。因此,模式大体上应该是这样的

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

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

在这种情况下,async/await的使用有什么秘密?

然后版本相比,不多。但是,您说“外部库不期望从这个回调中获得返回值”,这可能暗示了库与异步回调不兼容,所以要当心您在做什么。它还可能取决于从回调同步抛出的异常,所以这完全取决于库在这里期望什么(如果没有期望,将来是否会改变)。您不希望将来出现不兼容,以防库开始特别处理promise返回值。

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

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
}));
 类似资料:
  • 前言 大家学JavaScript的时候,经常遇到自执行匿名函数的代码,今天我们主要就来想想说一下自执行。 在详细了解这个之前,我们来谈了解一下“自执行”这个叫法,本文对这个功能的叫法也不一定完全对,主要是看个人如何理解,因为有的人说立即调用,有的人说自动执行,所以你完全可以按照你自己的理解来取一个名字,不过我听很多人都叫它为“自执行”,但作者后面说了很多,来说服大家称呼为“立即调用的函数表达式”。

  • 主要内容:1.将函数转换为IIFE,2.IIFE的要点这是一个JavaScript函数,它会在定义后立即运行。 可以使用IIFE(立即调用函数表达式)来避免从块内部进行变量吊装。 它允许公开访问方法,同时保留函数中定义的变量的私密性。 IIFE是一种设计模式,也称为自执行匿名函数。它包含两个主要部分: 第一部分是具有词法范围的匿名函数,该函数包含在分组运算符中。 第二部分创建IIFE,JavaScript引擎将通过该IIFE直接解释该函数。 语法:

  • 问题内容: 我正在尝试编译的React项目上工作,但找不到为什么我遇到此语法错误。具体来说,在这种情况下,模式“ {{)=> {}()}”在做什么? 代码部分: 问题答案: 这是立即调用的函数expression。 您的代码有误? 您需要将函数包装在()中,检查以下内容: 在这种情况下,“ {()=> {}()}”模式在做什么? 直接地,我们不能将if / else语句或任何其他语句放在JSX中,

  • 问题内容: 有一个JSLint选项(实际上是The Good Parts之一),它“需要避免立即调用”,这意味着构造 而是需要写成 我的问题是-谁能解释为什么第二种形式可能会更好?它更具弹性吗?容易出错?与第一种形式相比,它有什么优势? 自问了这个问题之后,我开始理解在功能值和功能值之间进行清晰的视觉区分的重要性。考虑一下立即调用的结果在赋值表达式的右侧的情况: 尽管从语法上讲,最外面的括号不是必

  • 为什么这在Node.js控制台(在4.1.1和5.3.0中测试)中工作,但在浏览器中不工作(在Chrome中测试)? 这个代码块应该创建并调用一个匿名函数,该函数记录。 另外,当上述操作在节点中工作时。js,这不起作用: 也不是这个: 奇怪的是,当添加参数时,它实际上会在立即调用的部分抛出一个。

  • 问题内容: 首先,这是一个非常特殊的情况,它以错误的方式故意将异步调用改型为一个非常同步的代码库,该代码库长成千上万行,并且当前时间不具备进行更改的能力。对的。” 它伤害了我的每一个生命,但是现实和理想往往并没有相互融合。我知道这很糟糕。 好的,顺便说一句,我该如何做,这样我可以: 示例(或缺少示例)全部使用库和/或编译器,这两种库均不适用于此解决方案。我需要一个如何使其冻结的具体示例(例如,在调