TypeScript class 正在变成另一个 class

TypeScript class is turning into another class

在我看来,这是一个非常基本的问题,但我花了几个小时试图弄清楚这个问题,却无法解决这个问题。

我有一个名为 WSManager 的 class,它有多种方法可以使用 ws 模块和 Discord API 来管理 WebSocket 连接.由于一些奇怪的原因,我的 class 变成了 class 内部的 WebSocket 实例,这很奇怪,因为我现在无法访问 handleHello 方法。

我得到的错误:

TypeError: this.handleHello is not a function
    at WebSocket.handleWSMessage (/home/samthefam/Projects/Official/Personal/discord-halo/src/WSManager.ts:51:25)
    at WebSocket.emit (events.js:375:28)
    at Receiver.receiverOnMessage (/home/samthefam/Projects/Official/Personal/discord-halo/node_modules/ws/lib/websocket.js:833:20)
    at Receiver.emit (events.js:375:28)
    at Receiver.dataMessage (/home/samthefam/Projects/Official/Personal/discord-halo/node_modules/ws/lib/receiver.js:517:14)
    at Receiver.getData (/home/samthefam/Projects/Official/Personal/discord-halo/node_modules/ws/lib/receiver.js:435:17)
    at Receiver.startLoop (/home/samthefam/Projects/Official/Personal/discord-halo/node_modules/ws/lib/receiver.js:143:22)
    at Receiver._write (/home/samthefam/Projects/Official/Personal/discord-halo/node_modules/ws/lib/receiver.js:78:10)
    at writeOrBuffer (internal/streams/writable.js:358:12)
    at Receiver.Writable.write (internal/streams/writable.js:303:10)
[ERROR] 08:07:20 TypeError: this.handleHello is not a function

以下是脚本的重要部分:

// ...imports

class WSManager {
    private ws?: WebSocket;
    
    constructor(private client: Client)
        // ...initalise properties
    }

    public async connect(): Promise<void> {
        this.ws = await this.createWebSocket(); // This is the line that appears to cause 'this' to turn into 'this.ws', however it doesn't break until 'this.handleHello()' strangely.
        this.handleWSConnection();
    }

    private handleWSConnection(): void {
        this.ws.on("message", this.handleWSMessage);
        // ...other events
    }

    private handleWSMessage(rawData: string): void {
        // ...do stuff
        this.handleHello();
    }

    public async getWSEndpoint(token: string): Promise<string> {
        const { data: wsEndpointData }: { data: WSEndpointData } =
            await axios.get(`${apiEndpoint}/gateway/bot`, {
                headers: {
                    Authorization: `Bot ${token}`,
                },
            });

        return wsEndpointData.url;
    }

    private async createWebSocket() {
        const wsEndpoint = await this.getWSEndpoint(this.client.token);

        return new WebSocket(
            `${wsEndpoint}/?v=${config.gatewayVersion}&encoding=json`
        );
    }

    handleHello(data: HelloData): void {
        const hbInterval: number = data.d.heartbeat_interval;
        this.hbData.d = data.s;
        this.sequenceNumber = data.s;

        setTimeout(() => {
            this.heartbeat();

            setInterval(() => {
                this.heartbeat();
            }, hbInterval);
        }, hbInterval * Math.random());

        this.identify();
    }
}

export default WSManager;

将不胜感激。

发生这种情况是因为调用 handleWSMessage 时没有 this 绑定到您的对象。

问题在这里:

this.ws.on("message", this.handleWSMessage);

改为:

this.ws.on("message", data => this.handleWSMessage(data));