Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Can';t从回调中设置类成员变量_Javascript_Redis_Ecmascript 6 - Fatal编程技术网

Javascript Can';t从回调中设置类成员变量

Javascript Can';t从回调中设置类成员变量,javascript,redis,ecmascript-6,Javascript,Redis,Ecmascript 6,我正试图通过从类构造函数调用的函数的回调来设置类成员变量 更具体一点:我需要根据Redis INCR结果在连接类构造函数中设置连接ID(每个客户端都有一个“全局”连接ID,因此我可以有多个节点) 这是密码 class Connection { constructor() { client.incr('conn_id', (err, reply) => { this.connID = reply; }); } } var lovely = new Con

我正试图通过从类构造函数调用的函数的回调来设置类成员变量

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

这是密码

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

var lovely = new Connection();
console.log(`lovely connID is ${ lovely.connID }`);
这是结果:
connID未定义

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

所以

log(
可爱的connID是${lavely.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

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

所以

log(
可爱的connID是${lavely.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


正如其他人所提到的,问题似乎在于
client.incr
是异步的,您的代码在访问属性之前不会等待它被解析。要解决此问题,您可以尝试将
onReady
回调传递到
Connection
,以确保在尝试访问属性之前属性将在那里。大致如下:

“严格使用”;
//mock client.incr
var客户端={incr:(id,回调)=>{
setTimeout(()=>callback(null,'Hello World'),0)
}};
类连接{
//接收“onReady”函数
构造函数(onReady){
client.incr('conn_id',(err,reply)=>{
this.connID=回复;
//调用“onReady”函数,并将其传递给类
if(typeof onReady==='function')onReady(this)
});
}
}

新连接(lovely=>{console.log(lovely.connID)}
正如其他人所提到的,问题似乎是
client.incr
是异步的,您的代码在访问属性之前不会等待它的解析。要解决此问题,您可以尝试将
onReady
回调传递到
Connection
,以确保在尝试访问属性之前属性将在那里。大致如下:

“严格使用”;
//mock client.incr
var客户端={incr:(id,回调)=>{
setTimeout(()=>callback(null,'Hello World'),0)
}};
类连接{
//接收“onReady”函数
构造函数(onReady){
client.incr('conn_id',(err,reply)=>{
this.connID=回复;
//调用“onReady”函数,并将其传递给类
if(typeof onReady==='function')onReady(this)
});
}
}

新连接(lovely=>{console.log(lovely.connID)}
一般来说,在构造函数中放入大量的初始化逻辑,特别是异步的,不是一个好主意。正如您所发现的,构造函数无法返回初始化何时完成的信息。另一种方法是创建连接准备就绪时的承诺。然后,在外部代码中,您可以挂起一个
Then
属性,以指定准备就绪时要trun的代码

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 }`);

一般来说,在构造函数中放入大量的初始化逻辑,特别是在异步的情况下,不是一个好主意。正如您所发现的,构造函数无法返回初始化何时完成的信息。另一种方法是创建连接准备就绪时的承诺。然后,在外部代码中,您可以挂起一个
Then
属性,以指定准备就绪时要trun的代码

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 }`);

不熟悉Redis,但它是
client.incr
异步的吗?这可能意味着在对client.incr的回调有机会运行之前,您正在运行console.log行。请参阅。您的问题不是“无法从回调中设置类成员变量”,而是“无法在设置类成员变量之前访问它”。不熟悉Redis,但是
client.incr
异步的?这可能意味着您在对client.incr的回调有机会运行之前正在运行console.log行。请参阅。您的问题不是“无法从回调中设置类成员变量”,而是“无法在设置类成员变量之前访问它”。当然,那么他应该如何修复它?如果他需要记录它,他应该在回调中这样做,如果他需要做更多的事情,他可以在回调中调用一个函数;我的意思是,你的答案遗漏了这一部分,应该加以补充。从构造函数内部进行日志记录不是很好。如果我想从构造函数外部登录呢?当然,那么他应该如何修复它呢?如果他需要登录,他应该在回调中这样做,如果他需要做更多的事情,他可以在回调中调用函数,我不是在问我自己;我的意思是,你的答案遗漏了这一部分,应该加以补充。从构造函数内部进行日志记录不是很好。如果我想从构造函数之外登录呢?在这个承诺的时代,我们仍然在使用回调?如果他想访问构造函数外部的
connId
,该怎么办;他怎么知道它是否准备好了呢?@torazaburo我把它看作是一种直截了当的方式,用以证明什么是错的,以及事件的顺序是如何发生的——而不是最终的实现(因此用了一句话:“……沿着……的路线的东西”)。如果OP想在了解数据流后使用承诺,那么就这样吧,他/她可以使用您的答案作为指导。感谢您提供的替代方案。在这个充满承诺的时代,我们仍然在使用回调?如果他想访问施工现场以外的
connId
,该怎么办