【问题标题】:Typescript/javascript method being invoked before constructor在构造函数之前调用 Typescript/javascript 方法
【发布时间】: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 关于在构造函数中使用异步操作的信息,这些操作存在另一组问题,因为构造函数必须返回新对象,因此它不能轻易返回承诺让调用者知道异步操作何时完成.

标签: node.js typescript postgresql


【解决方案1】:

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

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

  1. 类构造函数运行
  2. this.client.connect 被调用,并被传递一个函数以在它(最终)连接时运行。
  3. 构造函数完成执行。
  4. psql.retreiveImageData() 被执行
  5. 不知过了多久,传递给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之前等待回调被调用。

【讨论】:

    猜你喜欢
    • 2015-08-20
    • 1970-01-01
    • 2018-08-20
    • 1970-01-01
    • 1970-01-01
    • 2013-05-08
    • 2012-09-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多