如何在回调函数中访问“ this”的两个上下文?

时间:2019-08-27 06:24:54

标签: javascript node.js

class MyExampleClass {
    constructor(port, service) {
        this.port = port;
        this.service = service;
        this.app = require('express')();
        this.http = require('http').createServer(this.app);
    }

    onListening() {
        // Current result: 'listening on port NaN for undefined'
        // Desired result: 'listening on port 3000 for test' (I want to CHANGE this behavior)
        console.log('listening on port %d for %s', this.port, this.service);

        // Current result: 'class: Server'
        // Desired result: 'class: Server' (I want to KEEP this behavior)
        console.log('class: ' + this.constructor.name);
    }

    start() {
        this.http.listen(this.port, this.onListening);
    }
}

const example = new MyExampleClass(3000, 'test');
example.start();

正如onListening方法的注释所述,我想访问MyExampleClass实例的上下文和Server创建的createServer的回调实例的上下文。

4 个答案:

答案 0 :(得分:4)

在构造函数中绑定this.onListening,将this上下文保留在onListening中。

您不能让this指向2个不同的上下文,因此您将不得不通过Server访问this.http实例。

class MyExampleClass {
    constructor(port, service) {
        this.port = port;
        this.service = service;
        this.app = require('express')();
        this.http = require('http').createServer(this.app);

        this.onListening = this.onListening.bind(this);
    }

    onListening() {
        console.log('listening on port %d for %s', this.port, this.service);
        console.log('class: ' + this.http.constructor.name);
    }

    start() {
        this.http.listen(this.port, this.onListening);
    }
}

const example = new MyExampleClass(3000, 'test');
example.start();

答案 1 :(得分:2)

只需在bind(this)这样的回调引用上使用this.http.listen(this.port, this.onListening.bind(this));

遵循代码将起作用


class ExampleServer {
    constructor(port, service) {
        this.port = port;
        this.service = service;
        this.app = require('express')();
        this.http = require('http').createServer(this.app);
    }

    onListening() {
        // I want to access the context for the instance of `ExampleServer`, but `this` is the context for the instance of `Server` created by `createServer`.
        console.log('listening on port %d for %s', this.port, this.service);

        // I want to also still be able to access the context for the instance of `Server` created by `createServer`, which is what the below is already doing.
        console.log(this.http.constructor);
    }

    start() {
        this.http.listen(this.port, this.onListening.bind(this));
    }
}

const server = new ExampleServer(3000, 'test');
server.start();

答案 2 :(得分:2)

使用箭头功能

class ExampleServer {
  constructor (port, service) {
    this.port = port
    this.service = service
    this.app = require('express')()
    this.http = require('http').createServer(this.app)
  }

  onListening = () => {
    console.log('listening on port %d for %s', this.port, this.service)
  }

  start = () => {
    this.http.listen(this.port, this.onListening)
  }
}

const server = new ExampleServer(3000, 'test')
server.start()

答案 3 :(得分:-4)

这样的事情怎么样?

onListening(server=null) {
   const self = this;
        // I want to access the context for the instance of `ExampleServer`, but `this` is the context for the instance of `Server` created by `createServer`.
       if(server){
            console.log('listening on port %d for %s', server.port, server.service);
       }
        // I want to also still be able to access the context for the instance of `Server` created by `createServer`, which is what the below is already doing.
        console.log(self);
    }