是否总是需要使用 await 调用异步函数?

Posted

技术标签:

【中文标题】是否总是需要使用 await 调用异步函数?【英文标题】:Does an async function always need to be called with await? 【发布时间】:2020-05-14 04:14:45 【问题描述】:

首先,我有一个异步函数,它在 MongoDB 数据库上记录消息。

async function log_message(sender, conversationId, text) 
    try 
        const msg = new Message(
            sender: sender,
            conversationId: conversationId,
            text: text
        );
        await msg.save();
        console.log("Done");
     catch (e) 
        console.log("An error happened while logging the message: " + e)
    

现在,我有另一个异步函数,当我收到消息并负责处理它并获取一些数据时会触发它。 一旦触发此函数,我就会调用“log_message”将消息记录在我的数据库中,但我不想用 await 调用它,否则,我会等到“log_message”函数返回,然后再处理减慢消息的消息消息处理。

    async getReply(username, message) 
        log_message("user", username, message);
        console.log("HI");
        let reply = await this.rs.reply(username, message, this);
        return reply;
    

尽管如此,Jetbrains Webstorm 还是给了我这个警告“缺少等待异步函数调用”。 现在,我做了一些测试,如果我在没有等待的情况下调用函数,系统会按预期运行,消息会得到处理,并且我的日志记录函数会异步地将数据写入数据库而不会中断。 相反,如果我在调用日志记录函数之前放置了 await 关键字,则主函数中代码的执行将暂停,直到数据库尚未写入。

有人可以告诉我,我打算使用 async/await 关键字的方式是否存在一些缺陷?

【问题讨论】:

完全没问题。如果需要,您可以在 IDE 中静默警告。 回答你的问题:像你一样使用它完全没问题。另一方面,您的log_message 不需要异步,因为它只是在消息保存后记录消息Done。我不会仅仅因为这个原因让它异步。 这能回答你的问题吗? Async function without await in javascript @ArunKumarSaini 不是async函数内部是否必须有await,而是async函数是否必须用await关键字调用 【参考方案1】:

如果您的逻辑不需要async 调用的结果,则没有必要。尽管在您的情况下不需要,documentation 列出了启用该警告的两个好处:

虽然这通常不是必需的,但它有两个主要好处。 第一个是在使用 try-catch 包围代码时,您不会忘记添加“等待”。 第二个是明确的“等待”有助于 V8 运行时提供异步堆栈跟踪

【讨论】:

【参考方案2】:

当您将 async 设置为方法时,该方法期望在其范围内使用 await。因为 async 关键字的功能就像您告诉方法在其范围内还有另一个必须完成的进程才能继续进行方法进程。

换句话说,如果您不想等待其他进程完成,那么您应该避免在方法中使用 async 关键字。

这里,await 关键字是有意义的:

await msg.save();

因为它会等待直到它在日志完成之前保存。但是在您希望全部运行而不等待其他进程结束的方法中。只是不要使用 asyn 关键字。如果你不想在这里等待:

await this.rs.reply(username, message, this);

不要在这里使用异步:

async getReply(username, message)

如果您需要在 getReply 中等待某些内容,则应添加 async 关键字,否则,不需要该关键字。

【讨论】:

【参考方案3】:

当你想要等待某个操作时,你必须将 await 与该操作关联,但在将 await 与该操作关联之前,您需要使父函数异步。

【讨论】:

【参考方案4】:

虽然我看到你在这里有答案。

现在让我告诉你!

异步函数不一定需要在其中进行 await 调用,但使函数异步背后的原因是您需要一个异步调用,您希望在线程中前进之前等待其结果。

async getReply(username, message) 
        log_message("user", username, message);
        console.log("HI");
        let reply = await this.rs.reply(username, message, this);
        return reply;
    

上面的函数可以工作,但你为什么要让它异步呢?由于您没有使用任何异步功能。如果使用如下,它的工作原理相同:-

getReply(username, message) 
        log_message("user", username, message);
        console.log("HI");
        let reply = await this.rs.reply(username, message, this);
        return reply;
    

【讨论】:

getReply 函数需要异步,否则 let reply = await this.rs.reply(username, message, this); 中的 await 关键字不被接受。不过,我的问题是关于“log_message”之前缺少等待的警告 @Moltehh log_message 应该有 await 因为它是异步的,警告很有帮助。

以上是关于是否总是需要使用 await 调用异步函数?的主要内容,如果未能解决你的问题,请参考以下文章

异步/等待:异步嵌套函数是不是需要自动等待上一级?

swift 异步 async/await 的使用

async await 同步方法调用异步方法死锁

“异步”调用图中的最后一次调用是不是需要同步?

使用异步而不等待

学会使用async/await