for-loop의 setTimeout이 연속된 값을 인쇄하지 않음
다음 스크립트가 있습니다.
for (var i = 1; i <= 2; i++) {
setTimeout(function() { alert(i) }, 100);
}
★★★★★★★★★★★★★★★★★.3
번 됩니다.1
2
.
지나갈 수 있는 방법이 있나요?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);
}
그 이유는!
- 타임아웃 함수 콜백은 모두 루프 완료 후 정상적으로 실행됩니다.실제로 타이머에 따라 각 반복에서 setTimeout(.., 0)이 되어도 모든 함수 콜백은 루프가 완료된 후에도 엄밀하게 실행되므로 3이 반영되었습니다.
- 이러한 두 함수는 모두 각 루프 반복에서 개별적으로 정의되지만 동일한 공유 글로벌 스코프에서 닫힙니다. 실제로 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
'programing' 카테고리의 다른 글
JSON과 JSONP의 차이점은 무엇입니까? (0) | 2022.10.10 |
---|---|
INSERT INTO SELECT는 매우 느리지만 INSERT 또는 SELECT는 여러 번 실행할 때 빠릅니다. (0) | 2022.10.10 |
기존 데이터베이스가 있는 Mariadb 다단계 컨테이너 (0) | 2022.10.10 |
Vuetify : 카드 내 2줄 (0) | 2022.10.10 |
array_diff()가 어레이에서 문자열 변환 오류를 발생시키는 이유는 무엇입니까? (0) | 2022.10.10 |