无法从回调中设置类成员变量

时间:2016-06-24 16:32:28

标签: javascript redis ecmascript-6

我试图从我从类构造函数调用的函数的回调中设置一个类成员变量。

更具体一点:我需要根据Redis INCR结果在Connection类构造函数中设置连接ID(每个客户端都有一个'全局'连接ID,所以我可以有多个节点)

这是代码。

Rectangle

结果如下:class Connection { constructor() { client.incr('conn_id', (err, reply) => { this.connID = reply; }); } } var lovely = new Connection(); console.log(`lovely connID is ${ lovely.connID }`);

4 个答案:

答案 0 :(得分:0)

似乎client.incr(' conn_id' ....)是异步的,这意味着在代码运行后将调用回调。

所以

的console.log(lovely connID is ${ lovely.connID });将在回调之前调用

  

(错误,回复)=> {         self.connID =回复;       }

与此类似:

class Connection{
  constructor(){
    self=this;
    setTimeout( function(){self.client='somevalue';
                          console.log('value1');}, 10)

  }
}

var a = new Connection();

console.log(a.client); 

运行此结果

  

未定义        值1

答案 1 :(得分:0)

正如其他人提到的那样,问题似乎是client.incr是异步的,并且您的代码在访问属性之前不会等待它解析。要解决此问题,您可以尝试将onReady回调传递给Connection,以确保在尝试访问属性之前属性将存在。这些方面的东西:

'use strict';

// mock client.incr
var client = { incr: (id, callback) => {
  setTimeout(() => callback(null, 'Hello World'), 0) 
}};

class Connection {
  // receive an "onReady" function
  constructor(onReady) {
    client.incr('conn_id', (err, reply) => {
      this.connID = reply;
      // call "onReady" function, and pass it the class
      if (typeof onReady === 'function') onReady(this)
    });
  }
}

new Connection(lovely => { console.log(lovely.connID) })

我希望有所帮助!

答案 2 :(得分:0)

通常在构造函数中放置大量的初始化逻辑,特别是如果它是异步的,不是一个好主意。正如您所发现的,构造函数无法返回有关何时完成初始化的信息。另一种方法是在连接准备就绪时创建一个承诺。然后,在您的外部代码中,您可以将then挂起,以指定您准备好的代码。

class Connection {
  constructor() {
    this.connId = new Promise((resolve, reject) =>
      client.incr('conn_id', (err, reply) => {
        if (err) return reject(err);
        resolve(reply);
    });
  }
}

var lovely = new Connection();
lovely.connId . then(connId => console.log(`lovely connID is ${ connID }`);

答案 3 :(得分:-2)

您在回调中使用this,可能不会引用同一个对象。如果您可以将上下文对象设置为client.incr()的参数,请尝试这样做。否则使用self是常见的解决方法之一:

class Connection {
  constructor() {
    var self = this // Keep a reference to the current "this"
    client.incr('conn_id', (err, reply) => {
      self.connID = reply;
    });
  }
}