2012-04-18 4 views
4

변수 setTimeout을 전달하고 그 함수를 사용하고 싶습니다. 내가 i의 가치를 경고 할 때 그것은 내가 예상하지 못한 숫자를 보여줍니다. 내가 뭘 잘못하고 있니?변수를 익명 함수로 전달하는 방법

setTimeout(function(a, b, c) { 
    console.log(a, b, c); 
    }, 1000, 'a', 'b', 'c'); 

Source : 나는 8

var end=8; 
for (var i = 1; i < end; i ++) { 
     setTimeout(function (i) { 
      console.log(i); 

     }, 800); 
    } 
+0

맞습니까? 오류가 있습니까? – Starx

+1

문제는 범위 문제입니다 :'for' 카운터 변수는'i'라고하지만, 매개 변수는'i'라고합니다. 따라서 매개 변수 -i 범위에있는 즉시 counter-i에있는 모든 값을 덮어 씁니다. 카운터 또는 매개 변수의 이름을 변경하면 도움이됩니다. –

+0

@DominikSchreiber : 부분적으로 * 범위 문제입니다. 그러나'i' 인수를 제거하거나 이름을 바꾸는 것으로는 해결되지 않습니다. –

답변

-2

setTimeout 추가 인수로 변수를 받아까지 1의 값을 기록합니다.

편집 : 예제에서는 루프가 완료된 후 함수를 호출하기 만하므로 i의 유효 값은 8 일 수 있습니다. |

var end=8; 
for (var i = 1; i < end; i ++) { 
     setTimeout(makeResponder(i), 800); 
    } 

function makeResponder(index) { 
    return function() { 
     console.log(index); 
    }; 
} 

Live example :

var end=8; 
for (var i = 1; i < end; i ++) { 
    setTimeout(function (i) { 
     console.log(i); 
    }, 800, i); 
} 
+1

염두에 두라 "** 첫 번째 구문의 함수에 추가 매개 변수를 전달하는 것이 Internet Explorer에서는 작동하지 않습니다 ** ** –

+0

IE에 대해서는 항상 이전의 (그러나 비추천) 구문을 사용할 수 있습니다 :'setTimeout (' callable ('+ i +') ', 1000);'. – Iso

+0

** IE9 **에서는 작동하지 않습니다. 훨씬 이전 버전입니다. 이 답변은 2018 년경에 유용 할 수 있습니다. –

11

이 문제를 해결하는 표준 방법은 공장 기능을 사용하는 것입니다 : 각 호출에 대해 i의 현재 값을 전달해야 source

루프에서이

, 우리 전화makeResponder, 그리고 그것을 (index)에 전달 된 인수보다는 i 변수를 통해 닫 함수를 반환합니다. (중요합니다. 익명 함수에서 i 인수를 제거한 경우 코드가 부분적으로 작동하지만 처음 예약되었을 때가 아니라 으로 실행될 때 모든 함수의 값이 i으로 표시됩니다. 귀하의 예를 들어, 그들은 모두 8 볼 것)


업데이트을 아래에 귀하의 의견에서 :.

... 난 그런 식으로 setTimeout(makeResponder(i),i*800);에 전화를하는 경우가 올바른 것인가?

당신의 목표는 각 호출을하는 경우 예, 나중에 마지막으로보다 800ms, 즉 작동 거의 발생합니다

Live example을 |

source 나는 setTimeout(makeResponder(i),setInterval(i));function setInterval(index) { console.log(index*800); return index*800; }을 시도했지만 제대로

당신은 setInterval 그런 식으로 사용하지 않는 작동하지, 그리고 아마 모든이를 위해 그것을 사용하지 않습니다.


는 또한 갱신 :

내가 첫 번째 반복 인쇄 8 지연 8 초, 두 번째 반복 인쇄 7 초 ........ 인쇄 (7) 지연이 필요합니다 : 당신은 아래 말한 2 지연 2 초 ... 인쇄 0 지연 0 초.

당신은 단지 두 번째 시간 제한 사용하여, 위의 다시 원칙을 적용

var end=8; 
for (var i = 1; i < end; i ++) { 
     setTimeout(makeResponder(i), i * 800); 
    } 

function makeResponder(index) { 
    return function() { 
     var thisStart = new Date(); 
     console.log("index = " + index + ", first function triggered"); 
     setTimeout(function() { 
      console.log("index = " + 
         index + 
         ", second function triggered after a further " + 
         (new Date() - thisStart) + 
         "ms delay"); 
     }, index * 1000); 
    }; 
} 

Live example을 | source

이제는 앞으로해야 할 모든 도구가 있다고 생각합니다.

+0

안녕하세요, 고마워, 그게 올바른 방식으로 전화를 setTimeout (makeResponder (i), i * 800); 나는이 부분이 i * 800이라는 것을 의미한다. – alexeyb

+0

setTimeout (makeResponder (i), setInterval (i)); function setInterval (index) { console.log (index * 800); return index * 800; }하지만 제대로 작동하지 않습니다. – alexeyb

+0

@alexeyb : 위 질문에 대한 답변을 추가했습니다. –

0

setTimeout800i 이후에 실행되도록 설정되어 있기 때문에 이것이 작동하지 않는 주된 이유가 있습니다.

i 값이 이미 변경 될 때까지 실행됩니다. 따라서 결정적인 결과를 얻을 수 없습니다. TJ가 말한 것처럼, 이것을 처리하는 방법은 핸들러 함수를 사용하는 것입니다. 당신의 setTimeout() 기능 화재 다음으로, i의 값이 변경되면

function handler(var1) { 
    return function() { 
     console.log(var1); 
    }   
} 

var end = 8; 
for (var i = 1; i < end; i++) {  
    setTimeout(handler(i), 800); 
} 

Demo

1

귀하의 문제는 당신이 시간 이후 변수 i 언급하는 것입니다 (그것은 for의 끝으로 사라 이 i의 적절한 값의와 루프., 각 setTimeout() 콜백에 대해 개별적으로 그 값 i을 캡처 한 각의 setTimeout을 유지합니다.

이전 답을 사실상를 사용하여 ry 함수는 괜찮 았지만 자습 함수는 입력하고 따르는 공장 기능보다 약간 쉽지만 두 함수 모두 closure에서 원하는 변수를 포착하여 setTimeout 콜백에서 정적 값을 참조 할 수 있기 때문에 둘 다 작동 할 수 있습니다. 여기

가 자체 실행 기능이 문제를 해결하기 위해 작동 할 방법은 다음과 같습니다

var end=8; 
for (var i = 1; i < end; i ++) { 
     (function (index) { 
      setTimeout(function() { 
       console.log(index); 
      }, 800); 
     })(i); 
    } 

i의 값에 비례하여 제한 시간 지연을 설정하려면를, 당신은이 작업을 수행 할 것입니다 :

var end=8; 
for (var i = 1; i < end; i ++) { 
    (function (index) { 
     setTimeout(function() { 
      console.log(index); 
     }, index * 800); 
    })(i); 
} 

자체 실행 함수는 i의 값을 전달하고 그 값을 포함하는 해당 함수의 인수는 index으로 명명되므로 index을 참조하여 적절한 값을 사용할 수 있습니다.

+0

괜찮 았어.하지만 시간 제한을 설정하고 싶다면 ... 어떻게해야합니까? 예를 들어, 각 번호와 지연 번호 * 800을 입력하고 싶다면 i * 800을 추가하면 모든 루프가 변경 될 때마다 1 초가 지연됩니다. – alexeyb

+0

@alexeyb - 당신은'index'라는 이름의 인자를 사용합니다. 내 답변에 추가 한 두 번째 예제를 참조하십시오. – jfriend00

관련 문제