2012-01-11 2 views
2

루프에서 setTimeout의 함수 호출에 문제가 있습니다.
함수에 전달 된 매개 변수는 각 반복마다 루프에서 계산 된 마지막 값입니다. 아래 예제를 참조하십시오.

Javascript : setTimeout 및 참조의 함수

for(var i=0; i<datesYM.length; ++i) { 
    console.log(datesYM[i]); 
    var dateYM = datesYM[i]; 
    setTimeout(function() { 
     myDB.markMonthsValuesAsUpdated2(myDoctorId, dateYM) 
    }, Math.floor(Math.random()*5001)); 
} 

myDB.markMonthsValuesAsUpdated2 = function(myDoctorId, dateYM) { 
    console.log(dateYM); 
    [...] 

인쇄 :

2012-01
2012-02
2012-03
2012-04
2012-05
2012-06
2012-07

2012-07
2012-07
2012-07
2012-07
2012-07
2012-07
2012-07

답변

5

랩의 새로운 범위를 강제로 자신의 자기 실행 기능의 몸이없이

for(var i=0; i<datesYM.length; ++i) { 
    console.log(datesYM[i]); 
    var dateYM = datesYM[i]; 
    (function(dateYM) { 
     setTimeout(function() { 
      myDB.markMonthsValuesAsUpdated2(myDoctorId, dateYM) 
     }, Math.floor(Math.random()*5001)); 
    })(dateYM); 
} 

을, 루프에서 생성 된 모든 함수는 동일 인스턴스dateYM 인 닫음이며,이 함수는 해당 함수가 실행될 때까지 마지막 반복 값을가집니다. JavaScript에는 함수 범위가 있으므로 래퍼 함수는 각 반복마다 dateYM을 새로 작성하므로 setTimeout에 전달 된 새 함수마다 자체 인스턴스가 있습니다.

1

타임 아웃 처리기를 생성하고 반환하는 함수를 통해 가변 범위를 만듭니다.

그런 다음 해당 함수를 호출하고 범위가 필요한 모든 것을 전달하십시오. 당신이 setTimeout에 부여 된 모든 기능이 동일한 변수 범위에 만들어지는 때문에

setTimeout(create_timeout_handler(myDoctorId, dateYM), Math.floor(Math.random()*5001)); 

이다, 그래서 그들은 모든 루프에 덮어 쓰는 것과 같은 dateYM 변수를 참조했다.

dateYM을 처리기를 생성하고 반환하는 다른 함수에 전달하면 각 처리기가 create_timeout_handler의 각 호출에 고유 한 변수 인 dateYM을 참조하도록합니다.

관련 문제