think-serious
think-serious

Reputation: 1319

Why use async without await in Javascript?

I have seen so many people defining async function without using await in it like this.

async function authMiddleware(req, res, next) => {
  try {
    const token = req.query.token
    const secret = process.env.JWT_SECRET
    jwt.verify(token, secret)
  } catch (err) {
    return res.status(403).json({ message: MESSAGES.TOKEN_EXPIRED })
  }
  return next()
}

I've attached this code just for an example. Please don't care the meaning of lines inside.

Is there any good point or use case of defining a function as async without any await in javascript?

Possibly: is it possible that he intended to inform the user that it returns promise?

Upvotes: 4

Views: 7911

Answers (4)

t.niese
t.niese

Reputation: 40842

For you shown code, it does not make any sense, because it is - at least I assume - an express middleware and expressjs does not use the returned Promise of that middleware. And without an await in that async middleware the only thing that changes is that the middleware returns a Promise, and as expressjs does not use that returned Promise, so the async keyword here is pointless and can be even harmful, if the something in authMiddleware throws a not cached error.

And it does not make sense to use it without any reason. You can use async and await to convert an otherwise long-running synchronous process into smaller chunks so that other code can interleave, as await/async allows you introduce some kind cooperative multitasking. But only adding await/async to a long-running task alone would not prevent you from blocking the event loop.

If you have a code like this:

function testA() {
   for( let i=0 ; i<10 ; i++) {
      console.log('testA', i)
   }
}

function testB() {

   for( let i=0 ; i<10 ; i++) {
      console.log('testB', i)
   }
}

testA();
testB();

console.log('finished');

Then you could use await and async to allow other code to interleave, by changing it to.

async function testA() {
  for (let i = 0; i < 10; i++) {
    console.log('testA', await i)
  }
}

async function testB() {

  for (let i = 0; i < 10; i++) {
    console.log('testB', await i)
  }
}

Promise.all([
  testA(),
  testB()
]).then(() => {
  console.log('finished');
})

Upvotes: 1

Arash Shakery
Arash Shakery

Reputation: 102

For the example code provided, I guess the developer had intentions of making it asynchronous (not blocking event-loop) in the future but he didn't know an easy way to do so. The thing is jwt.verify doesn't provide a Promise based API, it accepts an optional third callback parameter in which case it will be executed asynchronously. Again I guess the developer wasn't confident about using callback API, or he has been religious about using async/await wherever possible.

A possible solution using async/await, could be to promisify jwt.verify and await on that promisified function call:

const verifyJwtAsync = Bluebird.promisify(jwt.verify);

async function authMiddleware(req, res, next) => {
  try {
    const token = req.query.token
    const secret = process.env.JWT_SECRET
    await verifyJwtAsync(token, secret)
  } catch (err) {
    return res.status(403).json({ message: MESSAGES.TOKEN_EXPIRED })
  }
  return next()
}

A simpler callback-based solution is as follows:

async function authMiddleware(req, res, next) => {
    const token = req.query.token
    const secret = process.env.JWT_SECRET
    jwt.verify(token, secret, function(err) {
       if (err) res.status(403).json({ message: MESSAGES.TOKEN_EXPIRED });
       else next();
    })
}

Upvotes: 0

Zeeshan
Zeeshan

Reputation: 47

Above written code is intended to returning an implicit Promise as its result.

Like

async function firstFunction(a , b) {
   do some stuff here.....
}
function secondFunction(res){
 do some stuff here.....
}
async function thirdFunction(items){
 const data = await fetch('url here');
 const result = await data.json();
 do some stuff here........
}

so Here is the deal....

firstFunction(2,3) .then((resOfFirst) => secondFunction(resOfFirst)) .then((resOfSecond) => thirdFunction(resOfSecond))

Hope this will help.

Upvotes: 0

user12603016
user12603016

Reputation:

What ESLint says with its rule require-await.

Asynchronous functions in JavaScript behave differently than other functions in two important ways:

  • The return value is always a Promise.
  • You can use the await operator inside of them.

The primary reason to use asynchronous functions is typically to use the await operator, ...

What MDN says :

The async function declaration defines an asynchronous function — a function that returns an AsyncFunction object. Asynchronous functions operate in a separate order than the rest of the code via the event loop, returning an implicit Promise as its result. But the syntax and structure of code using async functions looks like standard synchronous functions.

It is clear that async functions are not only made for await use. Then, not having await in an async function is ok. But... what is the point ?

I believe it is to use a synchronous function like a Promise. The following example is from javascript.info.

async function f() {
  return 1;
}

f().then(alert); // 1

Would be the same as:

async function f() {
  return Promise.resolve(1);
}

f().then(alert); // 1

Is there any good point of defining a function as async without any reason in javascript?

It may be used to make code more readable or easy to follow.

Results client-side will not be impacted.

Upvotes: 5

Related Questions