programing

for-loop의 setTimeout이 연속된 값을 인쇄하지 않음

nicescript 2022. 10. 10. 20:30
반응형

for-loop의 setTimeout이 연속된 값을 인쇄하지 않음

다음 스크립트가 있습니다.

for (var i = 1; i <= 2; i++) {
    setTimeout(function() { alert(i) }, 100);
}

★★★★★★★★★★★★★★★★★.3번 됩니다.12.

지나갈 수 있는 방법이 있나요?i수를문 문자 ?? ????

각 타임아웃 함수에 대해 "i"의 개별 복사본이 존재하도록 준비해야 합니다.

function doSetTimeout(i) {
  setTimeout(function() { alert(i); }, 100);
}

for (var i = 1; i <= 2; ++i)
  doSetTimeout(i);

이와 같은 작업을 수행하지 않으면(그리고 이 같은 아이디어에 대한 다른 변형도 있음), 각 타이머 핸들러 함수는 동일한 변수 "i"를 공유합니다.루프가 끝나면 "i"의 값은 얼마입니까?3입니다! 중간 함수를 사용하여 변수 값의 복사를 만듭니다.타임아웃 핸들러는 그 카피의 컨텍스트에서 작성되기 때문에, 사용하는 전용의 「i」가 있습니다.

edit : 타임아웃을 몇 개 설정하면 모든 핸들러가 동시에 기동하는 것에 대해 혼란스러운 코멘트가 몇 개 있었습니다.타이머를 설정하는 프로세스, 즉 콜을 이해하는 것이 중요합니다.setTimeout() 않습니다 - 시간이 전혀 않습니다. " call milliseconds 큐에 빠르기 에 " this function after 1000 milliseconds"가됩니다.

따라서 OP의 코드와 내 응답의 코드에서와 같이 타임아웃 요구가 연속적으로 발생하고 시간 지연 값이 각각 동일하면 그 시간이 경과하면 모든 타이머 핸들러가 차례로 호출됩니다.

는, 를 사용할 수 .setInterval() 해서 '아, 아, 맞다'와 똑같이 불려요.setTimeout()그러나 요청된 양의 반복 지연 후 두 번 이상 발생하거나, 시간 초과를 설정하고 시간 값에 반복 카운터를 곱할 수 있습니다. 예를 코드「」를 하려면 , 「」를 참조해 주세요.

function doScaledTimeout(i) {
  setTimeout(function() {
    alert(i);
  }, i * 5000);
}

( ( 께께))) )100밀리초의 타임아웃으로 효과는 그다지 뚜렷하지 않기 때문에 5000으로 올렸습니다.)「」의 값i는 기본 지연값에 곱하기 때문에 루프를 5회 호출하면 5초, 10초, 15초, 20초 및 25초의 지연이 발생합니다.

갱신하다

2018년에는 더 간단한 대안이 있습니다.함수보다 좁은 범위에서 변수를 선언하는 새로운 기능으로 원래 코드는 다음과 같이 수정되면 작동합니다.

for (let i = 1; i <= 2; i++) {
    setTimeout(function() { alert(i) }, 100);
}

let "Disclaration"는 달리var그 되는, 즉, 구별되는, 즉, ㄴㄴㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ,i각 루프의 반복에 대응합니다.

즉시 호출된 함수식(IIFE)을 사용하여 주위에 닫힘을 생성할 수 있습니다.setTimeout:

for (var i = 1; i <= 3; i++) {
    (function(index) {
        setTimeout(function() { alert(index); }, i * 1000);
    })(i);
}

이유는!

  1. 타임아웃 함수 콜백은 모두 루프 완료 후 정상적으로 실행됩니다.실제로 타이머에 따라 각 반복에서 setTimeout(.., 0)이 되어도 모든 함수 콜백은 루프가 완료된 후에도 엄밀하게 실행되므로 3이 반영되었습니다.
  2. 이러한 두 함수는 모두 각 루프 반복에서 개별적으로 정의되지만 동일한 공유 글로벌 스코프에서 닫힙니다. 실제로 i는 1개뿐입니다.

솔루션에서는 각 반복에 대해 하나의 범위를 선언하고 있습니다.이러한 경우, 자기 기능(익명의 IIFE 또는 그 이상의 IIFE)을 실행해, i 의 카피를 격납하고 있습니다.이러한 카피는 다음과 같습니다.

for (var i = 1; i <= 2; i++) {

     (function(){

         var j = i;
         setTimeout(function() { console.log(j) }, 100);

     })();

}

더 깨끗한 것은

for (var i = 1; i <= 2; i++) {

     (function(i){ 

         setTimeout(function() { console.log(i) }, 100);

     })(i);

}

각 반복 내에서 IIPE(자기실행함수)를 사용함으로써 각 반복에 대해 새로운 스코프가 생성되었습니다.이를 통해 타임아웃 함수는 각 반복에 대해 새로운 스코프를 종료할 수 있습니다.이 스코프에는 올바른 반복별 값을 가진 변수가 포함되어 있습니다.

" "에setTimeout루프 변수 위로 닫힙니다.인 """가 됩니다.i, 「」)3.

JavaScript 변수에는 함수 범위만 있기 때문에 해결책은 루프 변수를 타임아웃을 설정하는 함수에 전달하는 것입니다.다음과 같은 함수를 선언 및 호출할 수 있습니다.

for (var i = 1; i <= 2; i++) {
    (function (x) {
        setTimeout(function () { alert(x); }, 100);
    })(i);
}

추가 인수를 사용하여 콜백 함수에 파라미터를 전달하도록 설정할 수 있습니다.

for (var i = 1; i <= 2; i++) {
        setTimeout(function(j) { alert(j) }, 100, i);
}

주의: IE9 이하 브라우저에서는 동작하지 않습니다.

대답?

카트에 아이템을 추가하는 애니메이션에 사용하고 있습니다.제품 추가 버튼을 클릭하면 카트 아이콘이 카트 영역으로 이동합니다.

function addCartItem(opts) {
    for (var i=0; i<opts.qty; i++) {
        setTimeout(function() {
            console.log('ADDED ONE!');
        }, 1000*i);
    }
};

시간은 단위 곱하기 n epocs입니다.

클릭 순간부터 애니메이션 시작 epoc (각 애니메이션의)은 각 1초 단위의 곱에 아이템 수를 곱한 것입니다.

epoc : https://en.wikipedia.org/wiki/Epoch_(reference_date)

이게 도움이 됐으면 좋겠네요!

사용할 수 있습니다.bind방법

for (var i = 1, j = 1; i <= 3; i++, j++) {
    setTimeout(function() {
        alert(this);
    }.bind(i), j * 100);
}

Cody의 답변을 바탕으로 한 또 다른 효과적인 솔루션은 다음과 같습니다.

function timedAlert(msg, timing){
    setTimeout(function(){
        alert(msg);    
    }, timing);
}

function yourFunction(time, counter){
    for (var i = 1; i <= counter; i++) {
        var msg = i, timing = i * time * 1000; //this is in seconds
        timedAlert (msg, timing);
    };
}

yourFunction(timeInSeconds, counter); // well here are the values of your choice.

이런 식으로 해결했을 때 나도 같은 문제가 있었어.

2초 간격으로 12개의 지연을 발생시킨다고 가정합니다.

    function animate(i){
         myVar=setTimeout(function(){
            alert(i);
            if(i==12){
              clearTimeout(myVar);
              return;
            }
           animate(i+1)
         },2000)
    }

    var i=1; //i is the start point 1 to 12 that is
    animate(i); //1,2,3,4..12 will be alerted with 2 sec delay

진정한 해결책은 여기 있지만 PHP 프로그래밍 언어에 익숙해야 합니다.목적에 도달하려면 PHP와 JavASCript 주문을 혼합해야 합니다.

이 점에 주의해 주십시오.

<?php 
for($i=1;$i<=3;$i++){
echo "<script language='javascript' >
setTimeout(function(){alert('".$i."');},3000);  
</script>";
}
?> 

당신이 원하는 대로 할 수 있지만, PHP 변수와 JavASCript 변수를 구분하는 방법에 주의하세요.

언급URL : https://stackoverflow.com/questions/5226285/settimeout-in-for-loop-does-not-print-consecutive-values

반응형