【问题标题】:calling an async function in the constructor.在构造函数中调用异步函数。
【发布时间】:2018-09-16 14:23:01
【问题描述】:

getUser 是一个异步函数吗?如果需要更长的时间来解决?它会在我的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());
     }
 }

【问题讨论】:

标签: javascript asynchronous ecmascript-6 identityserver4


【解决方案1】:

这是一个与this popular question有关的问题。

一旦代码是异步的,就不能以同步的方式使用。如果不需要使用原始承诺,则应使用async 函数执行所有控制流。

这里的问题是getUser 提供了用户数据的承诺,而不是用户数据本身。构造函数中丢失了一个承诺,这是反模式。

解决问题的一种方法是为IdpServer 提供初始化承诺,而其余的API 将是同步的:

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();

根据应用程序的工作方式,IdpServer.initializationPromise 可以在应用程序初始化时进行处理,以保证所有依赖于IdpServer 的单元在准备好之前不会被初始化。

另一种方法是使IdpServer 完全异步:

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();

预计所有依赖它的单元也将具有异步 API。

【讨论】:

  • 这是新的实现,@estus 这是一个 int 函数,至少在应用程序中的 20 个地方使用了该函数。只是在想是否有更简单的方法,以便只需要最少的更改。
  • 因为这是设计错误,应该重构。如果存在承诺,则应该有一种方法将其链接到依赖于该承诺结果的地方。我想第一种方式需要的改动更少,而且通常更常见。
  • 只是想让你们知道,我修复了它,将它作为第一个运行的东西,只有当它解决时,路由器才会渲染页面模板。
猜你喜欢
  • 2020-07-28
  • 2014-05-27
  • 2017-04-14
  • 2012-08-05
  • 2013-12-27
  • 1970-01-01
  • 2014-10-28
相关资源
最近更新 更多