2011-02-07 7 views
6

브라우저가 'this'로 간주하는 것에 문제가 있습니다. 다음 예제에서 abc의 pingMe()를 호출하면 1 초가 경과 한 후 브라우저는 Object DOMWindow에 'func'메서드가 없음을 알립니다. 'this'를 ABC (abc) 클래스의 인스턴스로 해석하는 대신, 객체가 포함되지 않은 것처럼 DOMWindow로 해석됩니다. setTimeout이 콜백 범위와 관련하여 어떻게 작동하는지 명확히 이해하지 못하고 있습니다. 어떤 제안이 어떻게이 콜백을 성공시킬 수 있습니까?콜백 스크립트 타이머와 콜백시 'this'포인터

class ABC 
    @func = null 

    constructor: (func) -> 
    @func = func 

    pingMe: -> 
    setTimeout(doPing, 1000) 

    doPing = -> 
    @func() 

abc = new ABC -> 
    alert "HI" 
abc.pingMe() 
+1

hm, setTimeout 라인을'obj = this;로 바꾼다. setTimeout ((-> obj.doPing()), 1000)'doPing 선언을 doPing : ->로 수정 한 것으로 보입니다. CoffeeScript가 이러한 시나리오에서 정기적 인 JavaScript 동작을 유지하는 것처럼 보입니다. – Larry

답변

10

이 코드가 작동합니다.

class ABC 
    @func = null 

    constructor: (func) -> 
    @func = func 

    pingMe: -> 
    setTimeout => 
    @doPing() 
    , 1000 

    doPing: -> 
    @func() 

abc = new ABC -> 
    alert "HI" 
abc.pingMe() 

귀하의 도핑 방법은 다른 모든 name: ->를 사용하는 반면, 나는 그런 식으로 변경, doPing = ->을 정의 하였다. pingMe은 익명 함수를 만들기 위해 =>을 사용하고, this을 함수에 바인딩하기 위해 @doPing을 사용합니다.

이것이 맞는지 확실하지 않은 경우, 거의 JavaScript를 사용하지 않습니다. 그러나 그것이 당신에게 더 나아갈 방향을 줄 수 있기를 바랍니다.

+0

네. '=>'에 대한 나의 지식은 부족했다. – Larry

0

아마도 좀 더 명확하게하기 위해 "doPing"메서드를 바인딩 할 수 있습니다. 조금 더 깨끗해 보일 것입니다. FWIW, 나는 그것이 당신이 성취하고자하는 것을 더 잘 표현한다고 생각합니다.

class ABC 
    @func = null 

    constructor: (func) -> 
    @func = func 

    pingMe: -> 
    setTimeout => @doPing, 1000 

    doPing: => 
    @func() 

abc = new ABC -> 
    alert "HI" 
abc.pingMe() 
+0

나는 그것이'=> @doPing()'이어야한다고 생각한다. '=> @ doPing'은 바운드 함수를 호출하는 함수가 아니라 바운드 함수를 반환하는 함수로 평가됩니다. 라이너의 대답을보십시오. – joeytwiddle

1

당신이 ES5에서 어떻게 할 것인지에 가까운 대안 솔루션입니다 :

pingMe: -> 
    setTimeout (@doPing.bind @), 1000 

참고 bind이라고 :

pingMe: -> 
    setTimeout(@doPing.bind(@), 1000) 

또는 괄호에 저장하려는 경우 IE5에서만 IE에서 available 만 가능합니다.


또한 시도하는 모든 비용 피하기 유혹에 당신이해야주의 :

setTimeout(@doPing.bind @, 1000) # BAD! 
     or 
    setTimeout @doPing.bind @, 1000  # BAD! 

사람들 모두, bind에 두 번째 인수로 setTimeout을 수없는 통과하기 때문에!

관련 문제