2016-06-24 3 views
0

클래스 생성자에서 호출하는 함수의 콜백에서 클래스 멤버 변수를 설정하려고합니다.콜백에서 클래스 멤버 변수를 설정할 수 없습니다.

조금 더 구체적으로 : Redis INCR 결과 (각 클라이언트는 여러 개의 노드를 가질 수 있도록 '글로벌'연결 ID가 있음)를 기반으로 Connection 클래스 생성자에서 연결 ID를 설정해야합니다.

다음은 코드입니다. 당신은 같은 객체를 참조 할 수있는 콜백 내부 this 사용하는 lovely connID is undefined

+3

Redis에 익숙하지 않지만 'client.incr' 비동기식입니까? 즉, client.incr에 대한 콜백이 실행되기 전에 console.log 행을 실행 중일 수 있습니다. – rom99

+0

http : // stackoverflow를 참조하십시오.com/questions/34959257/why-isnt-my-future-value-available-now를 참조하십시오. –

+0

"클래스 멤버 변수를 콜백에서 설정할 수 없다"는 것이 아니라 "클래스 멤버 변수가 설정되기 전에 액세스 할 수 없다"는 것이 아닙니다. –

답변

-2

:

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

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

은 결과입니다. 컨텍스트 개체를 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

그것은 (... 'conn_id')이 client.incr 보인다 콜백 코드를 실행 한 후 호출됩니다 의미 비동기입니다.

그래서

을 console.log (lovely connID is ${ lovely.connID }); 콜백 전에 호출됩니다.

(오류, 응답) => { self.connID = reply; }이 유사하다

:이

정의되지 않은 값 1이

여기에 다른 언급했듯이
+0

예. 그렇다면 어떻게 수정해야합니까? –

+0

로깅이 필요한 경우 콜백 내부에서 수행해야하며 더 많은 작업을 수행해야한다면 콜백 내부에서 함수를 호출 할 수 있습니다. –

+0

나 자신을 요구하지 않았습니다. 나는 당신의 대답이이 부분을 빠뜨리고 증폭되어야한다고 제안했다. 생성자 내부에서 로깅은 그리 좋지 않습니다. 생성자 외부에서 로그하려면 어떻게해야합니까? –

0

, 문제가 보인다됩니다

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

    } 
} 

var a = new Connection(); 

console.log(a.client); 

실행 그게 client.incr 비동기이며 당신은 r 코드는 속성에 액세스하기 전에 해결하기를 기다리지 않습니다. 이 문제를 해결하기 위해 ConnectiononReady 콜백을 전달하여 속성에 액세스하려고 시도 할 수 있습니다. 이 라인을 따라 뭔가 :

'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

우리는 여전히 약속의 시대에 콜백을 사용하고 있습니까? 그가 생성자 외부의'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 }`); 
관련 문제