try catch 和 async await 的打字稿使用

typescript use of try catch and async await

你好,我想知道我是否正确使用了 async await 和 promise,基本上我使用了很多 try catch,在我看来所有这些 try catch 都不是必需的

我有这个主要的 class:

export class BootstrapApplication {
  private server: WebServer;
  private knex: KnexInstance;
  constructor() {
    this.server = new ExpressServer();
    this.knex = container.resolve(KnexInstance);
  }
  public start = async () => {
    try {
      await this.knex.start(knexConfig);
      await this.server.start();
    } catch (error) {
      throw error;
    }
  };
}

并以此启动服务器:

(async () => {
  const server = new BootstrapApplication();
  await server.start();
})();

并且我在 bootstrap class 中有一个函数开始,我调用 knex.start 和我的异步 knex start 有 3 个使用 try catch 的异步函数:

@singleton()
export class KnexInstance {
  private knex: Knex;
  public get Knex() {
    return this.knex;
  }
  private assertDatabaseConnection = () => {
    return new Promise(resolve => {
      this.knex
        .raw('select 1+1 as result')
        .then(() => resolve())
        .catch(err => {
          console.log(
            '[Fatal] Failed to establish connection to database! Exiting...',
          );
          console.log(err);
          process.exit(1);
        });
    });
  };
  private runMigrations = async () => {
    try {
      console.log('Migration started...');
      await this.knex.migrate.latest({ loadExtensions: ['.ts'] });
      console.log('Migration finished...');
    } catch (err) {
      throw err;
    }
  };
  public start = async (config: Knex.Config) => {
    if (this.knex instanceof Knex) return;
    try {
      this.knex = Knex(config);
      await this.runMigrations();
      await this.assertDatabaseConnection();
    } catch (error) {
      throw error;
    }
  };
}

所以我怀疑我是否以错误的方式使用异步等待

try {
  // ...
} catch (e) {
  throw e;
}

^ 这始终是一个 no-op,在正常和 async 函数中什么都不做。

你是对的 - 在你的示例代码中,你可以安全地删除所有这些结构。

例如,您在 BootstrapApplication 中的 start() 方法可以等效地写为:

  public start = async () => {
    await this.knex.start(knexConfig);
    await this.server.start();
  };

请注意,您 不能 安全地删除 assertDatabaseConnection 中的 .catch(() => { ... },因为那样不会简单地重新抛出错误。

不过,您可以将 assertDatabaseConnection 简化很多。你根本不需要 new Promise,因为你已经有了承诺,所以你可以简化为:

  private assertDatabaseConnection = async () => {
    try {
      await this.knex.raw('select 1+1 as result')
    } catch (err) {
      console.log(
        '[Fatal] Failed to establish connection to database! Exiting...',
      );
      console.log(err);
      process.exit(1);
    }
  };

一般来说,new Promise 在异步代码中的大多数情况下都不需要,只有在极少数情况下才真正需要,主要是在将 callback/event-driven 代码转换为 promise 时。