2012-11-15 2 views
3

최근에 for 루프에서 지연된 jquery의 동작에 대해 질문했습니다. Link herefor 루프의 jQuery 지연 동작

작동하는 답변을 받았지만 작동하는 이유를 모르겠습니다.

나는 다음과 같은 코드가있는 경우 :

function updateElements(deferreds) { 
    for (var i = 0; i < 5; i++) { 
     var index = i; 
     deferreds.push(update({ 
      success: function() { 
       alert(index); 
      } 
     })); 
    } 
}; 

그것은 5 경고를 반환 : 나는에 updateElements 방법을 변경하는 경우

function update(callbacks) { 
    return $.Deferred(function(dfr) { 
     setTimeout(function() { 
      callbacks.success() 
     }, 1000); 
     dfr.resolve(); 
    }).promise(); 
} 

function updateElements(deferreds) { 
    for (var i = 0; i < 5; i++) { 
     (function() { 
      var index = i; 
      deferreds.push(update({ 
       success: function() { 
        alert(index); 
       } 
      })); 
     })(); 
    } 
}; 

(function() { 
    var deffereds = []; 
    updateElements(deffereds); 
    $.when.apply($, deffereds).then(function() {}, function() {}); 
})();​ 

그것은 4까지의 값 0 5 개 경고 창을 반환합니다 값 4 만있는 창 누군가이 행동을 설명해 주시겠습니까? 차이점이 어디에서 발생하는지 이해하기 위해 고심하고 있습니다.

감사합니다. 만약

(function() { 
     var index = i; 
     deferreds.push(update({ 
      success: function() { 
       alert(index); 
      } 
     })); 
})(); 

이 전달 외부 값이 없기 때문에 실행 블록은 고정 값으로 전환이 자동으로 루프 닫혀 있기 때문에

+2

루프가 수를 갱신, 몇 밀리 초 단위로 실행하고 수를 표시하는 시간 변수에 의해, 비동기 및 대기입니다 연기 이후 변경되어 루프가 완료된 지 오래되었습니다. 익명 함수로 래핑 (wrapping)함으로써 각 반복에서 설정된 지역 변수이기 때문에'index' 변수의 값은 유지되고 갱신되지 않습니다. – adeneo

+0

[루프 내부의 Javascript 클로저 - 간단한 실용 사례] (http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) –

답변

3

는 그 않는다는 이유이다. 응답에서 사용자가 연결된 것처럼 그 값을 전달해야합니다. IEFE (즉시 실행 된 함수 표현식)의 끝에 값이 제공되는 주요 차이점에 유의하십시오. 죄송합니다 대문자,하지만이 강조해야합니다. 코드가이된다 그래서

(function(VALUE_ACCEPTED){ 
    //VALUE_ACCEPTED accepts the passed value of VALUE_PASSED 
})(VALUE_PASSED) 

:

function updateElements(deferreds) { 
for (var i = 0; i < 5; i++) { 
    (function(valueAccepted) { // valueAccepted = the passed in value from i 
     var index = valueAccepted; 
     deferreds.push(update({ 
      success: function() { 
       alert(index); 
      } 
     })); 
    })(i); // pass in i to valueAccepted 
} 
};