34

Basically, function must be prefixed with async keyword if await used inside it. But if some function just returns Promise and doesn't awaiting for anything, should I mark the function as async?

Seems like both correct or not?

// with async (returns Promise)
async getActiveQueue() {
   return redisClient.zrangeAsync(activeQueue, 0, -1);
}

// difference? Both could be awaited isn't it?
getActiveQueue() {
   return redisClient.zrangeAsync(activeQueue, 0, -1);
}
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
Maksim Nesterenko
  • 5,661
  • 11
  • 57
  • 91

4 Answers4

24

if some function just returns Promise and doesn't awaiting for anything, should I mark the function as async?

I would say you shouldn't. The purpose of async/await is to create (and resolve) the promise for you; if you already have a promise to return, then async/await won't give you any benefit for that function.

Both could be awaited isn't it?

await works on promises, not functions. So, await works fine on any promise, regardless of whether that promise is manually created or created behind the scenes by async.

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810
12

The async keyword is not only about allowing the await keyword in the function. It ensures that your function will always return a Promise, even when an exception is raised.

Here are code snippets showing the difference:

async function f(x) {
    if (!x)
        throw new Error('failed')

    return new Promise((resolve, reject) => {
        resolve(x + 1);
    });
}

f(false).then(
    result => console.log('f result', result),
    error => console.log('f async error', error)
);

If you don't add the async keyword and your function raises an exception, it will not be converted to a promise and you'll have to catch it synchronously.

function g(x) {
    if (!x)
        throw new Error('failed');

    return new Promise((resolve, reject) => {
        resolve(x + 1);
    });
}

try {
    g(false).then(
        result => console.log('g result', result),
    )
}
catch (error) {
    console.log('g sync error', error);
}
Boris Verkhovskiy
  • 14,854
  • 11
  • 100
  • 103
Eloims
  • 5,106
  • 4
  • 25
  • 41
11

If the function that you call for some unknown reason throws an error, async keyword will make sure that this will be returned as a rejected promise by your function.

async keyword might also be used in functions that would wish to return a promise (e.g. for api consistency) just from the return value, without the need to manually create a Promise object.

Due to the above, I would say that async keyword is not always paired with await.

Marinos An
  • 9,481
  • 6
  • 63
  • 96
0

If your function "doesn't awaiting for anything" - this is usual function, even inside your return function may be async ( this is incapsulation)...

Aleksandr Zolotov
  • 1,078
  • 3
  • 19
  • 32