在构造函数之前调用 Typescript/javascript 方法

Posted

技术标签:

【中文标题】在构造函数之前调用 Typescript/javascript 方法【英文标题】:Typescript/javascript method being invoked before constructor 【发布时间】:2021-08-21 01:25:42 【问题描述】:

所以我在创建 postgres 类时遇到了问题。但是,当连接到我的数据库时,我注意到在构造函数之前调用了一个函数。这是我的代码

import  Client  from 'pg';
import  Config  from './config/postgres'

class PostgresHandler 
    client: Client;
    status: boolean | undefined = false;
    constructor()
        this.client = new Client(Config)
        this.client.connect(err => 
            if (err) 
              console.error('connection error', err.stack)
              this.status = false
             else 
              console.log('connected')
              this.status = true
            
          )
    


    retreiveImageData() 
        console.log(this.status)
    


export PostgresHandler

调用这个类

 var psql = new PostgresHandler_1.PostgresHandler();
 psql.retreiveImageData()

输出:

false
connected

如何让我的构造函数在类中的任何其他方法之前先运行? 我正在尝试与 postgres 建立连接并将连接状态设置为 true。

【问题讨论】:

请参阅How do I return the response from an aynchronous call,这是重复的。换句话说,显然构造函数必须首先运行——但是你在构造函数中调用了一个异步方法,该方法在未来的任意时间返回。 首先,正如其他人所解释的,您需要了解非阻塞、异步操作的工作原理以及这对您的编码意味着什么。然后,您可以阅读this answer 关于在构造函数中使用异步操作的信息,这些操作存在另一组问题,因为构造函数必须返回新对象,因此它不能轻易返回承诺让调用者知道异步操作何时完成. 【参考方案1】:

您正在类构造函数中执行异步操作。 this.client.connect 将函数作为参数,以便让您知道它何时完成。

所以你的同步代码按这个顺序执行:

    类构造函数运行 this.client.connect 被调用,并被传递一个函数以在它(最终)连接时运行。 构造函数完成执行。 psql.retreiveImageData() 被执行 不知过了多久,传递给connect的回调被执行。

通常,您会将其包装在一个 Promise 中并在执行任何需要建立连接的操作之前等待它。但这有点棘手,因为类构造函数不能是async

一个好的解决方案是通过创建类来断开连接。这给了你更多的控制权。

这正是 pg 库所做的:

this.client = new Client(Config)
this.client.connect(err =>  //...

注意如何创建实例和连接是两个步骤。

你需要做同样的事情:

class PostgresHandler 
    client: Client;
    status: boolean | undefined = false;
    constructor()
        this.client = new Client(Config)
    

    async connect() 
      try 
        await this.client.connect()
        console.log('connected')
        this.status = true
       catch (err) 
        console.error('connection error', err.stack)
        this.status = false
      
    

    retreiveImageData() 
        console.log(this.status)
    

现在您可以await 将您的自定义类与:

async function someAsyncFunction() 
  var psql = new PostgresHandler();
  await psql.connect()
  psql.retreiveImageData() // Should log true once the connection is established.

someAsyncFunction()

或者:

var psql = new PostgresHandler();
psql.connect().then(() => 
  psql.retreiveImageData() // Should log true once the connection is established.
) 

Playground

【讨论】:

非常干净简洁的答案!这是正确的,并且能够实现我的目标。谢谢! 很高兴能帮上忙!如果它对您最有帮助,请不要忘记单击复选标记以将其选为正确答案。【参考方案2】:

this.client.connect 正在启动一个在后台运行的异步任务。在处理此调用时,您的其他代码会继续运行。因此,在建立连接时,this.status 将为 false。

解决方案: 在调用retrieveImageData之前等待回调被调用。

【讨论】:

以上是关于在构造函数之前调用 Typescript/javascript 方法的主要内容,如果未能解决你的问题,请参考以下文章

在构造函数之前调用 Typescript/javascript 方法

静态构造函数, 静态成员初始化/调用顺序

可以在调用构造函数之前完成赋值吗?

调用派生类的构造函数在基类的构造函数之前执行

在调用 Angular 构造函数之前捕获查询字符串

在 C++ QObject 子类中调用析构函数之前执行操作