【问题标题】:Async ES2017 Constructor异步 ES2017 构造函数
【发布时间】:2018-06-26 14:47:01
【问题描述】:

在随后使用该类之前,确保在类构造函数中完成某些异步代码的最新方法是什么?

具体来说,API 客户端类如何在允许更多方法调用之前检索访问令牌,如下所示?

class API_Client {

    constructor(...) {

        # Below should 'block' other method calls until token is assigned
        this.login().then(res => {
            this.token = res.data.token;
        });

    }

    async login() {
        return makeRequest(...) # <-- Promise which returns access token data
    }
}

const client = new API_Client(...);
client.someAuthOnlyMethod() # <-- Should only happen after the `login` method completes.

我找到了older answers,但不太明白如何解决链接答案留下的第一条评论中提出的问题。

【问题讨论】:

标签: javascript promise ecmascript-2017


【解决方案1】:

你不应该从构造函数调用任何异步代码开始。在上述情况下,您的 makeRequest 函数会担心登录令牌。

在这种情况下,类也没有真正的价值。您应该只导出一系列函数来进行 API 调用。

【讨论】:

  • 嗯,我的想法是这个类将支持几十个不同的端点请求以及同一“用户”的重复请求。为什么具有许多方法的类不是存储访问令牌以在许多不同请求中重复使用的合适解决方案?
  • 我想我的问题是,类与为每个端点导出单独函数的模块相比有什么好处? Javascript 不是基于类的语言——它更像是一种附加功能,你并没有真正从这里的类中获得任何好处。
【解决方案2】:

最新的方法仍然是not to put any asynchronous stuff in the constructor。在您的具体情况下,那是

class API_Client {
    constructor(token) {
        this.token = token;
    }
    static async createLoggedIn(…) {
        const res = await makeRequest(...) # <-- Promise which returns access token data
        return new this(res.data.token);
    }
}

const client = await API_Client.createLoggedIn(…);
client.someAuthOnlyMethod()

【讨论】:

  • 我认为您至少需要展示一些错误处理来处理登录失败时的情况,因为当您创建一个执行多项操作的工厂时,这部分会稍微复杂一些。
  • @jfriend00 它只是因承诺拒绝而失败。您可以将await 放在try/catch 中,只要您想处理错误(可能在调用API_Client.createLoggedIn 时)。一个做多种事情的工厂只会抛出不同的异常,不是吗?
  • 是的,我知道。不确定 OP 是否知道这一点。
【解决方案3】:

您可以将令牌存储为承诺:

class API_Client {

    constructor(...) {

        # Below should 'block' other method calls until token is assigned
        this.token = this.login()
          .then(res => res.data.token)

    }

    async someAuthOnlyMethod() {
      let token = await this.token;
      //...continue
    }

    async login() {
        return makeRequest(...) # <-- Promise which returns access token data
    }
}

const client = new API_Client(...);
client.someAuthOnlyMethod() # <-- Should only happen after the `login` method completes.

【讨论】:

  • 不要忘记在构造函数中安装默认错误处理程序以避免未处理的承诺拒绝
  • 有趣。我想我从来没有想过将承诺保存到变量中,但它足够直观。我在这里看到的主要缺点是令牌需要在每个经过身份验证的“调用”上重复设置——这几乎不是世界末日,但不是最优的。
猜你喜欢
  • 2012-08-05
  • 2013-12-27
  • 2014-10-28
  • 1970-01-01
  • 2017-04-14
  • 2011-12-30
  • 2017-09-11
相关资源
最近更新 更多