JavaScript wait for asynchronous function in if statement

77,846

Solution 1

I do this exact thing using async/await in my games code here

Assuming req.isLoggedIn() returns a boolean, it's as simple as:

const isLoggedIn = await req.isLoggedIn();
if (isLoggedIn) {
    // do login stuff
}

Or shorthand it to:

if (await req.isLoggedIn()) {
    // do stuff
} 

Make sure you have that inside an async function though!

Solution 2

You could promisify your function, like this:

req.isLoggedin = () => new Promise((resolve, reject) => {
    //passport-local
    if(req.isAuthenticated()) return resolve(true);

    //http-bearer
   passport.authenticate('bearer-login', (err, user) => {
       if (err) return reject(err);
       resolve(!!user);
   })(req, res);
});

And then you can do:

req.isLoggedin().then( isLoggedin => {
    if (isLoggedin) {
        console.log('user is logged in');
    }
}).catch( err => {
    console.log('there was an error:', err); 
});

Do not try to keep the synchronous pattern (if (req.isLoggeedin())), as it will lead to poorly designed code. Instead, embrace fully the asynchronous coding patterns: anything is possible with it.

Share:
77,846

Related videos on Youtube

pfMusk
Author by

pfMusk

Updated on March 18, 2020

Comments

  • pfMusk
    pfMusk about 4 years

    I have a function inside an if statement

    isLoggedin() has an async call.

    router.get('/', function(req, res, next) {
        if(req.isLoggedin()){ <- never returns true
            console.log('Authenticated!');
        } else {
            console.log('Unauthenticated');
        }
    });
    

    how do i await for isLoggedin() in this if statement?

    here is my isLoggedin function in which im using passport

    app.use(function (req, res, next) {
       req.isLoggedin = () => {
            //passport-local
            if(req.isAuthenticated()) return true;
    
            //http-bearer
           passport.authenticate('bearer-login',(err, user) => {
               if (err) throw err;
               if (!user) return false;
               return true;
    
           })(req, res);
       };
    
       next();
    });
    
  • pfMusk
    pfMusk over 6 years
    is there a way to use process.nextTick() instead? because i want to keep my syntax if(req.isLoggedin()){}
  • Sterling Archer
    Sterling Archer over 6 years
    Any particular reason why? I don't think synchronizing to the next event loop has a benefit over a Promise
  • pfMusk
    pfMusk over 6 years
    because i want to keep my syntax if(req.isLoggedin()){} :) would it be much more inefficient?
  • Sterling Archer
    Sterling Archer over 6 years
    The efficiently would be negligible, but nextTick does hold a higher efficiency because Promises create 2 and throws away one, but tbh I've never used nextTick to handle async behavior and I don't really know too many who do. I'll have to do some more research
  • Madara's Ghost
    Madara's Ghost over 6 years
    @pfMusk Please don't use process.nextTick for this. Just make the function async and use await, you-in-6-months would thank you.
  • pfMusk
    pfMusk over 6 years
    okok thank you @MadaraUchiha
  • trincot
    trincot over 2 years
    This answer is wrong. Putting await before a function call that returns a boolean, will not await the asynchronous authenticate process that the Asker has. I don't understand why this was marked as accepted.