【问题标题】:How to run Promise synchronously in TypeScript?如何在 TypeScript 中同步运行 Promise?
【发布时间】:2018-06-26 19:23:27
【问题描述】:

我有几个服务方法需要通过 Promise 初始化的第三方类实例(参见下面的代码:this.ready.resolve())。为了简化代码,我想将此初始化块放在构造函数中。

import { DBReady } from './db';

export class SampleService {
    private db: baqend;
    private ready: DBReady;

    constructor(private envVariables: IEnvSettings) {
        this.ready = new DBReady(envVariables);
        this.ready.resolve().then(db => {
            this.db = db;
        });            
    }

    public method1(id: string): Promise<boolean> {
        // this.db must be initialized here
    }
}

如何在构造函数中同步运行代码并根据method1 的请求初始化和访问this.db 实例?

【问题讨论】:

  • 不能,这是JS的限制。异步代码不能阻塞主线程。 method1 在访问 this.db 之前必须自己等待 this.ready
  • 有没有办法简化这段代码?我只是不想为一个类中的每个方法多次重复this.ready
  • 你需要在你的类中创建静态工厂并返回承诺
  • 你可以通过创建一个像getDB()这样的内部类方法来使它非常干净,它返回一个baqend的承诺然后使用async/await语法你的方法可以只使用const db = await this.getDB()并引用本地db 在函数体中。
  • 谢谢你 Aaron,我会继续你的建议 :) 刚刚测试过 - 效果很好。

标签: typescript promise


【解决方案1】:

您可以使用工厂方法来异步初始化您想要的内容

export class SampleService {
    private constructor(private db: DB) {}

    static init(envVariables: IEnvSettings) {
        return new DBReady(IEnvSettings).resolve().then(db => {
            return new SampleService(db);
        });
    }

    public method1(id: string) {
        this.db;
    }
}

SampleService.init({}).then(service => {
    service.method1();
});

// or
var service = await SampleService.init({});
service.method1();

【讨论】:

    【解决方案2】:

    这看起来不像是承诺?你是退回延期的吗?为什么要自己解决?

    我的建议是让函数返回一个真正的承诺,然后等待,并将调用函数标记为异步。当然,在构造函数内部是不行的,所以你必须把它移到一个 init 函数中。

    解决这个问题的一个很酷的方法是使用 Db 制作一个 @RequiresDb 装饰,并将其放在函数上,并使其异步。然后你只需在那里初始化数据库并缓存结果

    【讨论】:

    • SDK 承诺:baqend.com/guide/topics/getting-started/…。正如我之前提到的,Aaron 的方法对我有用。谢谢大家的帮助。
    • 如果你最终还是在整个地方跳了一个 await this.ready 舞。考虑创建一个装饰。它清理代码。
    猜你喜欢
    • 2019-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-05
    • 2015-12-26
    • 2018-01-19
    • 2018-01-15
    • 2018-08-11
    相关资源
    最近更新 更多