setTimeout 또는 setInterval?


763

내가 알 수있는 한이 두 가지 자바 스크립트는 동일한 방식으로 작동합니다.

옵션 A :

function myTimeoutFunction()
{
    doStuff();
    setTimeout(myTimeoutFunction, 1000);
}

myTimeoutFunction();

옵션 B :

function myTimeoutFunction()
{
    doStuff();
}

myTimeoutFunction();
setInterval(myTimeoutFunction, 1000);

setTimeoutsetInterval 사용에 차이가 있습니까?


6
JS의 타이머 작동 방식에 대한 자세한 내용을 보려면 John Resig 가이 주제에 대한 좋은 기사 를 작성했습니다
Rafael

9
또한 setTimeout은 코드를 전파하기 위해 추가 코드 줄이 필요하다는 명백한 차이점이 있습니다. 유지 관리 문제라는 단점이 있지만 기간을 쉽게 변경할 수 있다는 이점
annakata


4
@JapanPro에게 감사하지만 시간 초과가 발생하는 데 실제로 문제가 없었습니다. 이 게시물은 차이점과 사용해야 할 내용에 대한 내용입니다.
Damovisa

답변:


670

그들은 본질적으로 같은 일을하려고하지만 1000ms를 기다리고 함수를 실행 한 다음 다른 시간 초과를 설정하기 때문에 접근 방식 setInterval보다 접근 방식이 더 정확 합니다. 따라서 대기 시간은 실제로 1000ms 이상입니다 (또는 함수를 실행하는 데 시간이 오래 걸리면 더 큽니다).setTimeoutsetTimeout

정확히 1000ms마다 setInterval실행될 것이라고 생각할 수도 있지만 JavaScript는 다중 스레드 언어가 아니기 때문에 지연 될 것입니다. 즉, 스크립트의 다른 부분이 실행되면 간격이 그 끝날 때까지 기다리십시오.setInterval

이 Fiddle 에서는 시간 초과가 뒤 떨어지고 간격이 거의 항상 거의 1 호출 / 초 (스크립트가 시도하는 시간)임을 알 수 있습니다. 상단의 속도 변수를 20과 같은 작은 값으로 변경하면 (초당 50 회 실행 됨) 간격이 초당 평균 50 회에 도달하지 않습니다.

지연은 거의 무시할 만하지 만 실제로 정확한 것을 프로그래밍하는 경우 자체 조정 타이머 를 사용해야합니다 (기본적으로 타임 아웃 기반 타이머는 생성 된 지연에 따라 지속적으로 조정됩니다)


4
앤디도 비슷한 제안을했습니다. 가설로,이 방법이 실행하는 데 1000ms 이상이 걸리면 동시에 둘 이상을 실행할 수 있다는 의미입니까?
Damovisa 2009

14
이론적으로는 그렇습니다. 실제로 자바 스크립트는 멀티 스레딩을 지원하지 않기 때문에 없습니다. 코드가 1000ms보다 오래 걸리면 브라우저가 정지됩니다.
Kamiel Wanrooij 2009

61
기술적으로 코드 는 타이머의 해상도와 다른 코드가 이미 실행 중인지 여부에 따라 1000ms마다 정확히 실행되지 않습니다. 그래도 요점은 서 있습니다.
Matthew Crumley

10
setInterval은 두 가지 방식으로 다릅니다. setInterval은 재귀 적이 지 않으며 setInterval은 아무런 지연없이 setTimeout을 처음 호출 한 후 지정된 시간 후에 다시 호출합니다. 처음 실행 한 후에는 거의 동일하게 작동합니다.
Hafiz

5
차이점은 setTimeout이 자체 반복되지 않는다는 것입니다. 설정된 시간이 지난 후 한 번만 스크립트를 실행할 수 있습니다. 반면에 setInterval은 clearTimeout ()으로 중지 될 때까지 해당 스크립트를 반복합니다.
Leander

648

차이점이 있습니까?

예. 제한 시간은 setTimeout ()이 호출 된 후 일정 시간 동안 실행됩니다. 인터벌은 이전 인터벌이 발생한 후 특정 시간 동안 실행됩니다.

doStuff () 함수를 실행하는 데 시간이 걸리면 차이점을 알 수 있습니다. 예를 들어,로 setTimeout / setInterval에 대한 호출 .,로 시간 초과 / 간격 발생 *및로 JavaScript 코드 실행을 [-----]나타내는 경우 타임 라인은 다음과 같습니다.

Timeout:

.    *  .    *  .    *  .    *  .
     [--]    [--]    [--]    [--]

Interval:

.    *    *    *    *    *    *
     [--] [--] [--] [--] [--] [--]

다음 문제는 JavaScript가 이미 이전 작업 처리와 같은 작업을 수행하는 동안 간격이 발생하는 경우입니다. 이 경우 간격이 기억되며 이전 핸들러가 완료되고 브라우저로 제어를 리턴하는 즉시 발생합니다. 예를 들어 때때로 짧거나 ([-]) 때로는 ([-----]) doStuff () 프로세스의 경우 :

.    *    *        *        *    *
     [-]  [-----][-][-----][-][-]  [-]

• 코드를 바로 실행할 수없고 대신 보류중인 간격 발생을 나타냅니다.

따라서 간격은 일정을 다시 잡기 위해 '잡기'를 시도합니다. 그러나 이들은 서로를 대기열에 넣지 않습니다. 간격 당 하나의 실행 만 보류 할 수 있습니다. (모두 대기열에 있으면 브라우저는 계속해서 확장 된 미결 실행 목록으로 남게됩니다!)

.    *            x            x
     [------][------][------][------]

x는 실행할 수 없거나 보류중인 간격 발생을 나타내므로 대신 삭제되었습니다.

doStuff () 함수가 설정된 간격보다 습관적으로 실행하는 데 시간이 오래 걸리면 브라우저가 서비스를 시도하는 데 100 % CPU를 소모하고 응답 성이 떨어질 수 있습니다.

어느 것을 사용하고 왜?

Chained-Timeout은 브라우저에 자유 시간 슬롯을 보장합니다. 간격은 브라우저 UI 가용성을 희생하면서 실행중인 기능이 예약 된 시간에 최대한 가깝게 실행되도록합니다.

일회성 애니메이션에 대한 간격을 가능한 한 매끄럽게하고 싶었지만 체인 타임 아웃은 페이지가로드되는 동안 항상 진행되는 애니메이션에 더 정중합니다. 덜 까다로운 용도 (예 : 30 초마다 사소한 업데이터 실행 등)를 안전하게 사용할 수 있습니다.

브라우저 호환성 측면에서 setTimeout은 setInterval보다 우선하지만 오늘 만나게 될 모든 브라우저는 두 가지를 모두 지원합니다. 지난 몇 년 동안의 마지막 충격은 WinMo <6.5의 IE Mobile 이었지만 지금도 우리 뒤에 있습니다.


그러나 Interval과 Timeout을 선택하는 이유는 WebOS 또는 JIL과 같은 브라우저가 아닌 플랫폼에서도 마찬가지입니까?
Vid L

2
익명 함수에서 체인 타임 아웃을 수행하는 좋은 방법 : setTimeout (function () {setTimeout (arguments.callee, 10)}, 10)
Justin Meyer

1
브라우저 호환성 측면에서 모든 브라우저가 두 가지 방법을 모두 제공하지만 성능이 다릅니다.
unigg

"그러나 기회는 그것이 당신이 사용하고있는 다른 어떤 것도 지원하지 않을 것입니다"너무나 사실
Basic

1
setTimeout ( "schedule ()", 0)을 사용 하는 크롬 프로젝트에 의한 드럼 머신 ; 따라서 크롬의 배경 탭이거나 리소스가 부족할 때 브라우저에 불필요한 스택이 없습니다.
Elliot Yap

91

setInterval ()

setInterval()간격에 도달하면 지정된 스크립트를 반복적으로 실행할 수있는 기본 기능이있는 시간 간격 기반 코드 실행 방법입니다. 스크립트 작성자 가 기본적으로 루프하기 때문에 루프하기 위해 콜백 함수에 중첩 되어서는 안됩니다 . 호출하지 않으면 간격마다 계속 발사됩니다 .clearInterval()

애니메이션 또는 시계 눈금에 대한 코드를 반복하려면을 사용하십시오 setInterval().

function doStuff() {
    alert("run your code here when time interval is reached");
}
var myTimer = setInterval(doStuff, 5000);

setTimeout ()

setTimeout()간격에 도달하면 스크립트를 한 번만 실행하는 시간 기반 코드 실행 방법입니다 . 그것은 것입니다 하지 당신이 중첩에 의해 루프 스크립트를, 기어 않는 한 다시 반복 setTimeout()그것을 실행 호출 함수의 객체의 내부. 반복하도록 설정하면를 호출하지 않는 한 간격으로 계속 발사됩니다 clearTimeout().

function doStuff() {
    alert("run your code here when time interval is reached");
}
var myTimer = setTimeout(doStuff, 5000);

지정된 시간이 지난 후 한 번만 발생하려면을 사용하십시오 setTimeout(). 지정된 간격에 도달하면 한 번만 실행되기 때문입니다.


6
좋은 설명이지만 OP는 OP가 제공 한 예제의 기본적인 차이점을 이해합니다. 특히 OP의 setTimeout()예에서는 재귀 적setTimeout() 으로 호출 되는 반면 그렇지는 않습니다. setInterval()
DavidRR

44

setInterval을 사용하면 향후 코드 실행을 쉽게 취소 할 수 있습니다. setTimeout을 사용하는 경우 나중에 취소하려는 경우 타이머 ID를 추적해야합니다.

var timerId = null;
function myTimeoutFunction()
{
    doStuff();
    timerId = setTimeout(myTimeoutFunction, 1000);
}

myTimeoutFunction();

// later on...
clearTimeout(timerId);

function myTimeoutFunction()
{
    doStuff();
}

myTimeoutFunction();
var timerId = setInterval(myTimeoutFunction, 1000);

// later on...
clearInterval(timerId);

35
setInterval의 경우 타이머 ID를 추적하지 않는 방법을 모르겠습니다. 기능에서 벗어났습니다.
Kekoa

1
또 다른 옵션 setTimeout은 id를 저장하는 것이 아니라 if조건이 참일 때 다음 시간 초과 만 설정 하도록 명령문을 추가하는 것입니다.
nnnnnn

7
케 코아, 좋은 지적입니다. 그러나 간격 ID를 한 번만 저장해야합니다. 타임 아웃 ID는 매번 호출 될 때마다 변경 될 수 있으므로 이러한 변경 사항을 추적 해야합니다 . 타임 아웃을 지우려는 코드는이 변수의 현재 값에 액세스 할 수 있어야합니다. 또한 doStuffID가 유효하지 않기 때문에 실행 중에 시간 초과를 지우는 것은 불가능합니다 . 그러나 실제로 시간 초과 ID를 저장할 필요는 없습니다. 대신 당신은 그냥 전화를 중지 할 수 있습니다 setTimeout.
Robert

4
내 경험상 setTimeout을 사용하는 동안에도 대부분 취소 할 수 있기를 원합니다. 다음 호출이 완료된 가 아니라 다음 호출이 발생 하기 전에 취소하려는 시간의 99 %
Kamiel Wanrooij

23

내가 찾아 setTimeout당신은 시간 제한을 취소 할 경우 사용하기 쉬운 방법 :

function myTimeoutFunction() {
   doStuff();
   if (stillrunning) {
      setTimeout(myTimeoutFunction, 1000);
   }
}

myTimeoutFunction();

또한 함수에서 문제가 발생하면 매 초마다 오류를 반복하는 대신 첫 번째 오류에서 반복이 중지됩니다.


20

매우 다른 점은 그들의 목적에 있습니다.

setInterval()
   -> executes a function, over and over again, at specified time intervals  

setTimeout()
   -> executes a function, once, after waiting a specified number of milliseconds

그렇게 간단합니다

자세한 내용은 여기 http://javascript.info/tutorial/settimeout-setinterval


7
간결한 설명은 좋지만 OP는 OP가 제공 한 예제의 기본 차이점을 이해합니다. 특히 OP의 setTimeout()예에서는 재귀 적setTimeout() 으로 호출 되는 반면 그렇지는 않습니다. setInterval()
DavidRR

14

setInterval 내에서 일부 기능을 실행하면 시간 초과->보다 더 많은 시간이 작동하여 브라우저가 멈 춥니 다.

예 : doStuff () 는 1500 초가 걸립니다. 실행하려면 다음을 수행하십시오. setInterval (doStuff, 1000);
1) 브라우저에서 doStuff () 를 실행 하면 1.5 초가 걸립니다. 실행될;
2) ~ 1 초 후에 doStuff ()를 다시 실행하려고 시도 합니다. 그러나 이전 doStuff () 는 여전히 실행됩니다-> 브라우저는이 실행을 대기열에 추가합니다 (처음 완료 후 실행).
3,4, ..) 다음 반복을 위해 실행 대기열에 추가하는 것과 동일하지만 이전의 doStuff () 가 여전히 진행 중입니다 ...
결과적으로 브라우저가 멈췄습니다.

이 동작을 방지하려면 가장 좋은 방법은 setTimeout 내에서 setTimeout을 실행하여 setInterval을 에뮬레이트하는 것 입니다.
setTimeout 호출 사이의 시간 초과를 정정하려면 JavaScript의 setInterval 기술 대신 자체 수정 대안을 사용할 수 있습니다 .


1
왜 아무도이 답변에서 어떤 가치도 찾지 못했습니다!
Randika Vishman

9

setTimeout을 사용합니다.

분명히 차이점은 setTimeout은 메소드를 한 번 호출하고 setInterval은 반복적으로 호출한다는 것입니다.

다음은 차이점을 설명하는 좋은 기사입니다. 학습서 : setTimeout 및 setInterval이있는 JavaScript 타이머


2
그래, 그 차이가 있지만 내가 제공 한 두 가지 코드는 동일한 작업을 수행해야합니다.
Damovisa

음 .. 생각 했었 겠지만 .. dcaunt와 그의 투표 수에 따르면 그렇게되지는 않습니다.
Bravax 2009

9

코드는 실행 실행 간격이 다르며 온라인 게임과 같은 일부 프로젝트에서는 허용되지 않습니다. 먼저, 동일한 정수로 코드를 작동 시키려면 어떻게해야합니까? "myTimeoutFunction"을 다음과 같이 변경해야합니다.

function myTimeoutFunction()
{
    setTimeout(myTimeoutFunction, 1000);
    doStuff();
}
myTimeoutFunction()

이 변경 후에는

function myTimeoutFunction()
{
    doStuff();
}
myTimeoutFunction();
setInterval(myTimeoutFunction, 1000);

그러나 JS는 단일 스레드이기 때문에 여전히 안정적인 결과를 얻지 못할 것입니다. 현재 JS 스레드가 무언가에 바쁘면 콜백 함수를 실행할 수 없으며 실행이 2-3msec 동안 연기됩니다. 초당 60 회의 실행이 있고 임의의 1-3 초 지연이 발생할 때마다 1 분 후에는 약 7200msec 지연이 될 수 없으며 다음과 같이 사용하는 것이 좋습니다.

    function Timer(clb, timeout) {
        this.clb = clb;
        this.timeout = timeout;
        this.stopTimeout = null;
        this.precision = -1;
    }

    Timer.prototype.start = function() {
        var me = this;
        var now = new Date();
        if(me.precision === -1) {
            me.precision = now.getTime();
        }
        me.stopTimeout = setTimeout(function(){
            me.start()
        }, me.precision - now.getTime() + me.timeout);
        me.precision += me.timeout;
        me.clb();
    };

    Timer.prototype.stop = function() {
        clearTimeout(this.stopTimeout);
        this.precision = -1;
    };

    function myTimeoutFunction()
    {
        doStuff();
    }

    var timer = new Timer(myTimeoutFunction, 1000);
    timer.start();

이 코드는 안정적인 실행 기간을 보장합니다. 스레드조차도 바쁠 것이고 코드는 1005msec 후에 실행되며 다음에는 995msec 동안 시간 초과가 발생하며 결과는 안정적입니다.


7

setInterval(func, milisec)함수 시간 소비가 간격 지속 시간보다 클 때 어떤 일이 발생하는지 궁금 해서 간단한 테스트를 수행했습니다.

setInterval것입니다 일반적으로 단지 후 다음 반복 일정을 시작 , 이전 반복의 기능이 여전히 진행중인 경우를 제외하고 . 그렇다면 setInterval기능이 끝날 때까지 기다립니다. 그것이 발생하자마자 함수는 즉시 다시 시작됩니다-스케줄에 따라 다음 반복을 기다릴 필요가 없습니다 (시간을 초과하지 않는 조건 하에서). 병렬 반복이 실행되는 상황도 없습니다.

Chrome v23에서 이것을 테스트했습니다. 모든 최신 브라우저에서 결정적인 구현이기를 바랍니다.

window.setInterval(function(start) {
    console.log('fired: ' + (new Date().getTime() - start));
    wait();
  }, 1000, new Date().getTime());

콘솔 출력 :

fired: 1000    + ~2500 ajax call -.
fired: 3522    <------------------'
fired: 6032
fired: 8540
fired: 11048

wait기능은 스레드 차단 도우미- 서버 측에서 정확히 2500 밀리 초의 처리 가 필요한 동기식 아약스 호출입니다 .

function wait() {
    $.ajax({
        url: "...",
        async: false
    });
}

1
"병렬 반복이 실행되는 상황이 없습니다"-예, 불가능합니다. 클라이언트 측 JavaScript에는 단일 스레드 실행 모델이 있으므로 아무 것도 (이벤트 핸들러 등) 동시에 발생하지 않습니다. 동기 Ajax 호출 중에 아무 일도 일어나지 않고 브라우저가 응답하지 않는 이유입니다.
MrWhite

"간격"사이의 몇 ms 내에 브라우저가 반응합니까? 보류중인 다른 이벤트가 발생합니까? (테스트 btw +1 감사합니다)
MrWhite

1
MDN에 따르면 , 기능이 간격 시간보다 오래 실행될 수 있으면 " 위험한 사용 "으로 간주 됩니다. 재귀 setTimout호출이 선호됩니다.
MrWhite

6

조금 다르게 살펴보면 : setInterval은 코드가 주어진 간격마다 (즉, 1000ms 또는 얼마나 많이 지정하는지) 실행되도록하는 반면 setTimeout은 코드를 실행할 때까지 기다리는 시간을 설정합니다. 또한 코드를 실행하는 데 밀리 초가 더 걸리므로 최대 1000ms가 걸리므로 setTimeout은 정확하지 않은 시간 (1000ms 이상)에서 다시 실행됩니다.

예를 들어, 타이머 / 카운트 다운은 setTimeout으로 수행되지 않고 setInterval로 수행되어 지연되지 않고 코드가 지정된 간격으로 실행되도록합니다.


5

setInterval 및 setTimeout은 모두 실행을 취소하는 데 사용할 수있는 타이머 ID, 즉 시간 초과가 트리거되기 전에 타이머 ID를 반환합니다. 취소하려면 다음과 같이 clearInterval 또는 clearTimeout을 호출하십시오.

var timeoutId = setTimeout(someFunction, 1000);
clearTimeout(timeoutId);
var intervalId = setInterval(someFunction, 1000),
clearInterval(intervalId);

또한 페이지를 떠나거나 브라우저 창을 닫으면 시간 초과가 자동으로 취소됩니다.


4

다음 자바 스크립트를 실행 하거나이 JSFiddle을 확인할 때 bobince 답변을 직접 확인할 수 있습니다

<div id="timeout"></div>
<div id="interval"></div>

var timeout = 0;
var interval = 0;

function doTimeout(){
    $('#timeout').html(timeout);
    timeout++;
    setTimeout(doTimeout, 1);
}

function doInterval(){
    $('#interval').html(interval);
    interval++;
}

$(function(){
    doTimeout();
    doInterval();
    setInterval(doInterval, 1);
});

3

글쎄, setTimeout은 방금 배운 것처럼 한 상황에서 더 좋습니다. 나는 항상 setInterval을 사용하는데, 30 분 이상 동안 백그라운드에서 실행되도록 남겨 두었습니다. 해당 탭으로 다시 전환하면 슬라이드 쇼 (코드가 사용 된)가 5 초마다 바뀌지 않고 매우 빠르게 변경되었습니다. setTimeout을 사용하면 상황이 완전히 불가능하기 때문에 실제로 더 테스트하고 브라우저의 결함인지 여부는 중요하지 않습니다.


호출 한 함수 내에서 setInterval을 호출 한 것처럼 들립니다. 그렇게하면 setTimeout으로 루프하는 방법이지만 setInterval을 사용하면 호출 할 때마다 완전히 새로운 루프를 만듭니다.
Stephen R


2

이미 말한 내용을 추가하기 만하면 setTimeout 버전의 코드에 도달하여 Maximum call stack size작동하지 못하게됩니다. 재귀 함수가 중지되는 기본 사례가 없으므로 영원히 실행할 수 없습니다 .


나는 이것이 사실이라고 생각하지 않습니다. 여기를 참조하십시오 stackoverflow.com/questions/8058612/…
Kevin Wheeler

-1

와 setInterval (expression, duration)의 가장 일반적인 차이점은

setTimeout ()은 ONCE와 지정된 지속 시간 이후에만 표현식을 실행합니다.

하나,

setInterval ()은 지정된 각 지속 시간 후에 INFINITE-LOOP에서 표현식을 실행합니다.


-5

나는 생각 SetInterval하고 SetTimeout다르다. SetInterval설정된 시간에 따라 SetTimeout블록을 실행하고 코드 블록을 한 번 실행합니다.

시간 초과 카운트 다운 초 후에 다음 코드 세트를 시도하십시오.

setInterval(function(e){
    alert('Ugbana Kelvin');
}, 2000);

그리고 시도

setTimeout(function(e){
    alert('Ugbana Kelvin');
}, 2000);

당신은 자신의 차이점을 볼 수 있습니다.


이것은 질문에 대답하지 않습니다. settimeout ()을 재귀 적으로 사용하여 setinterval과 동일한 결과를 얻을 수 있습니다. 문제는이 두 가지 옵션의 성능에 관한 것이 었습니다.
Tomas Gonzalez
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.