2016-06-24 26 views
0

我想从我从类构造函数调用的函数的回调中设置类成员变量。为了更具体些:我需要根据Redis INCR结果(每个客户端都有一个“全局”连接ID,因此我可以有多个节点)在Connection类构造函数中设置连接ID。无法从回调中设置类成员变量

这是代码。

class Connection { 
    constructor() { 
    client.incr('conn_id', (err, reply) => { 
     this.connID = reply; 
    }); 
    } 
} 

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

这是结果:lovely connID is undefined

+3

不熟悉Redis,但是'client.incr'异步?这可能意味着在client.incr的回调有机会运行之前,您正在运行console.log行。 – rom99

+0

请参阅http:// stackoverflow。COM /问题/ 34959257 /为什么,心不是 - 我 - 未来的价值可供现在。 –

+0

你的问题不是你“不能从回调中设置类成员变量”,而是你“在设置之前不能访问类成员变量”。 –

回答

-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; 
    }); 
    } 
} 
+0

这就是为什么存在胖箭头符号。这里的问题是,正如@ rom99已经评论过的那样,“client.incr()'调用的异步性。 – robertklep

0

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

所以

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

(err,reply)=> { self.connID = reply; }

这是类似这样的:

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

    } 
} 

var a = new Connection(); 

console.log(a.client); 

运行,这将导致

不确定 值1

+0

当然,他应该如何解决它? –

+0

如果他需要记录它,他应该在回调中执行该操作,并且如果他需要做更多的事情,他可以在回调中调用一个函数 –

+0

我并不是要求自己;我建议你的答案缺少这部分,应该放大。从构造函数内部记录并不是那么好。如果我想从构造函数外部登录怎么办? –

0

正如其他人在这里所提到的,这个问题似乎是client.incr与你是异步的r代码在访问属性之前不会等待它解析。为了解决这个问题,您可以尝试将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) })

我希望帮助!

+0

我们仍在使用Promises这个时代的回调?如果他想访问构造函数外部的connId,该怎么办?他如何知道它是否准备好? –

+0

@torazaburo我认为这是一种直截了当的方式来证明什么是错误的,以及事件发生的顺序是如何发生的 - 而不是最终的实现(也就是说......“...... ......的某些事情”)。如果OP在理解数据流之后想要使用承诺,那就这样做吧,他/她可以用你的答案作为指导。感谢您提供替代方案。 –

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 }`); 
相关问题