Wednesday, June 5, 2024
141
rated 0 times [  144] [ 3]  / answers: 1 / hits: 18849  / 6 Years ago, fri, april 6, 2018, 12:00:00

getUser is an async function? if it is going to take longer time to resolve? is it going to always return the right value in my someotherclass.



class IdpServer {
constructor() {
this._settings = {
// some identity server settings.
};
this.userManager = new UserManager(this._settings);
this.getUser();
}

async getUser() {
this.user = await this.userManager.getUser();
}

isLoggedIn() {
return this.user != null && !this.user.expired;
}
}

let idpServer = new IdpServer();
export default idpServer;


// another class
// import IdpServer from '...'
class SomeOtherClass {
constructor() {
console.log(IdpServer.isLoggedIn());
}
}

More From » asynchronous

 Answers
178

This is a problem that is related to this popular question.



Once a code is asynchronous, it cannot be used in synchronous manner. If the use of raw promises is unwanted, all control flow should be performed with async functions.



The problem here is that getUser provides a promise of user data, not user data itself. A promise is lost in constructor, and this is antipattern.



One way to solve the problem is to provide initialization promise for IdpServer, while the rest of API will be synchronous:



class IdpServer {
constructor() {
...
this.initializationPromise = this.getUser();
}

async getUser() {
this.user = await this.userManager.getUser();
}

isLoggedIn() {
return this.user != null && !this.user.expired;
}
}

// inside async function
await idpServer.initializationPromise;
idpServer.isLoggedIn();


Depending on how the application works, IdpServer.initializationPromise can be handled on application initialization to guarantee that all units that depend on IdpServer won't be initialized until it's ready.



Another way is to make IdpServer entirely asynchronous:



class IdpServer {
constructor() {
...
this.user = this.getUser(); // a promise of user data
}

async getUser() {
return this.userManager.getUser();
}

async isLoggedIn() {
const user = await this.user;
return user != null && !user.expired;
}
}

// inside async function
await idpServer.isLoggedIn();


It's expected that all units that depend on it will also have asynchronous API.


[#54740] Wednesday, April 4, 2018, 6 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
iyannae

Total Points: 147
Total Questions: 88
Total Answers: 120

Location: Japan
Member since Sat, Jun 6, 2020
4 Years ago
;