我试图从我从类构造函数调用的函数的回调中设置一个类成员变量。
更具体一点:我需要根据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 }`);
答案 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;
});
}
}