Does an async function always need to be called with await?
Asked Answered
C

5

23

First some context, I have an async function which logs messages on a MongoDB database.

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

Now, I have another async function that gets triggered when I receive a message and takes care of processing it and fetching some data. As soon as this function get triggered I call "log_message" to log the message on my database, but I do not want to call it with await, otherwise, I would wait until the "log_message" function returns before processing the message slowing down the message processing.

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

Nevertheless, Jetbrains Webstorm gives me this warning "Missing await for an async function call". Now, I did some tests and if I call the function without await the system behaves as I expect, the message gets processed and my logging function writes the data on the db asynchronously without interrupting. If instead, I put the await keyword before calling the logging function the execution of the code in the main function gets suspended until the db has not been written.

Could someone tell me whether there are some flaws in the way I intended the usage of the async/await keywords?

Countryman answered 28/1, 2020 at 17:19 Comment(4)
It is completely fine. You can silent the warning in the IDE if needed.Manuscript
To answer your question: It's completely fine to use it as you already did. On the other hand, your log_message does not need to be async because it's just logging the message Done once the message it's saved. I would not make it async just for that reason only.Fossorial
Does this answer your question? Async function without await in JavascriptNewlywed
@ArunKumarSaini It is not whether there must be an await inside an async function, but whether an async function must be called with the await keywordCountryman
L
16

It is not necessary if your logic doesn't require the result of the async call. Although not needed in your case, the documentation lists two benefits to having that warning enabled:

While this is generally not necessary, it gives two main benefits. The first one is that you won't forget to add 'await' when surrounding your code with try-catch. The second one is that having explicit 'await' helps V8 runtime to provide async stack traces

Larvicide answered 28/1, 2020 at 17:28 Comment(0)
D
0

When you set async to a method, the method expects to use await inside its scope. Because the functionality of async keyword is like if you were telling to the method that inside its scope there's another process which must be completed before can proceed to the method process.

In other words, if you don't want to await to some other process to finish, then you should avoid async keyword in your method.

Here, makes sense the await keyword:

await msg.save();

Because it awaits till it's saved before log that is Done. But in the methods you want all run without waiting for other processes to end. Just don't use asyn keyword. If you don't want to await here:

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

Don't use async here:

async getReply(username, message)

If you need to await something in getReply then you should add async keyword, otherwise, is not necessary the keyword.

Deforest answered 28/1, 2020 at 17:31 Comment(0)
G
0

Whenever you want to await some operation you have to associate await with that but before associate await with that you need to make parent function async.

Greenwald answered 28/1, 2020 at 17:33 Comment(0)
T
0

Since you are already handling exceptions in your async log_message function, it is OK to ignore the Promise returned by that function. You can do that explicitly by adding the void suffix, when calling your function:

void log_message("user", username, message);

This will disable the "Missing await for an async function call" warning logged by your IDE.

But if your async function was NOT handling exceptions, then it is the responsibility of the caller to define how exceptions are to be handled. Either you await your function call, which would mean exceptions would be thrown to the caller, or you can append a .catch() to your function call, to define there how to handle exceptions:

async function log_message(sender, conversationId, text) {
    const msg = new Message({
        sender: sender,
        conversationId: conversationId,
        text: text
    });
    await msg.save();
    console.log("Done");
}

// Bug: exceptions thrown by log_message() are ignored. Bad, BAD idea!
async getReply_DontDoThat(username, message) {
    void log_message("user", username, message);
    console.log("HI");
    let reply = await this.rs.reply(username, message, this);
    return reply;
}

// Option 1: getReply will throw any exception generated in `log_message` to the caller
async getReply_ThrowExceptions(username, message) {
    await log_message("user", username, message);
    console.log("HI");
    let reply = await this.rs.reply(username, message, this);
    return reply;
}

// Option 2: getReply will handle exceptions
async getReply_HandleExceptions(username, message) {
    log_message("user", username, message).catch(
        (e) => console.log("An error happened while logging the message: " + e)
    );
    console.log("HI");
    let reply = await this.rs.reply(username, message, this);
    return reply;
}
Townscape answered 14/2 at 18:9 Comment(0)
G
-3

Though I see you have answers here.

Let me tell you the thing now!

Async functions are not necessarily required to have an await call inside it, but the reason behind making a function async is that you need an asynchronous call for which you want to wait for the result before moving forward in the thread.

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

The above function will work, but why exactly would you make it async? Since you aren't using any asynchronous functionality. It works the same if used as following:-

getReply(username, message) {
        log_message("user", username, message);
        console.log("HI");
        let reply = await this.rs.reply(username, message, this);
        return reply;
    }
Gridiron answered 28/1, 2020 at 17:35 Comment(2)
The getReply function NEED to be async otherwise the await keyword in let reply = await this.rs.reply(username, message, this); is not accepted. Still, my question is about the warning for the missing await before "log_message"Countryman
@Countryman The log_message should have await as it is async, The warning is helpful.Gridiron

© 2022 - 2024 — McMap. All rights reserved.