如何在nodejs的回调中修改外部范围变量的值

How do I modify the value of an external scope variable inside a callback in nodejs

下午好。 我获得了这个 Alexa 技能 class,在这个 class 中,我使用 mqtt 发送和接收消息。不幸的是,对于这个库,mqtt 消息需要回调。这是我的代码:

export class Launch implements RequestHandler {
    private readonly options = {
        host: 'host',
        port: 8883,
        protocol: 'mqtts',
        username: 'user',
        password: 'password'
    }

    private readonly mqttClient
    private listener: any
    private delayedPromise: any

    // @ts-ignore
    public constructor(private readonly skillHelper: SkillsHelperInterface) {
        this.mqttClient = mqtt.connect(this.options)
        this.mqttClient.on("connect",function() {
            console.log("connect");
        });
    }

    public canHandle(handlerInput: HandlerInput): Promise<boolean> | boolean {
        return this.skillHelper.isType(handlerInput, RequestTypes.Launch.toString())
    }

    public async handle(handlerInput: HandlerInput): Promise<Response> {
        this.waitForMessage(handlerInput, this.mqttClient, this.delayedPromise)

        this.mqttClient.publish("my/test/topic/publisher", "Hello")

        await this.delay(2000)

        return handlerInput.responseBuilder
            .speak(speechText)
            .reprompt(speechText)
            .getResponse()
    }

    waitForMessage(handlerInput: HandlerInput, mqttClient: MqttClient) {
        this.listener = function(topic: any, message: any) {
            // I want to update this class variable
            this.speechText = message.toString()
        }
        mqttClient.on("message", this.listener);
        mqttClient.subscribe("my/test/topic/subscriber");
    }

    delay(ms: number) {
        return new Promise( resolve => setTimeout(resolve, ms) );
    }
  }

我有一个名为“this.speechText”的变量,我想在调用侦听器后对其进行更新,但是一旦它退出侦听器,它就没有在侦听器中分配的值。我也试过将它传递给包含侦听器的方法,但它没有用。 我可以做些什么来更新回调中的外部范围变量吗?

提前致谢

出现此问题是因为您在使用 this 时处于不同的范围内。

解决问题,只需要将listener函数改成粗箭头函数即可,像这样:

this.listener = (topic: any, message: any) => {
   // I want to update this class variable
   this.speechText = message.toString()
};

使用箭头函数,this 引用 one-up 级别范围(如果存在)。当然,另一种方法是使用辅助变量指向对象而不是函数:

const _that = this; // Helper variable
this.listener = function(topic: any, message: any) => {
   // I want to update this class variable
   _that.speechText = message.toString()
};

但我建议你使用第一个选项。

如果您需要更多信息,请查看 mdn 上的文档:Fat Arrow Function