setInterval 함수를 처음 지연없이 실행


341

setInterval자바 스크립트 의 메소드 를 구성하여 메소드를 즉시 실행 한 다음 타이머로 실행하는 방법이 있습니다.


4
하지만 기본적으로는 아닙니다. 당신은 호출 시도 할 수 있습니다 function번을 한 후 일setInterval()
Mrchief

답변:


519

함수를 직접 직접 호출하는 것이 가장 간단합니다.

foo();
setInterval(foo, delay);

그러나 피해야 할 좋은 이유가 있습니다 setInterval. 특히 일부 상황에서는 모든 setInterval이벤트가 지연없이 서로 바로 도착할 수 있습니다. 또 다른 이유는 루프를 중지하려면 명시 적으로 호출 clearInterval해야하므로 원래 setInterval호출 에서 반환 된 핸들을 기억해야한다는 것 입니다.

따라서 다른 방법은 대신 다음을 foo사용하여 후속 호출에 대해 트리거하는 setTimeout것입니다.

function foo() {
   // do stuff
   // ...

   // and schedule a repeat
   setTimeout(foo, delay);
}

// start the cycle
foo();

이렇게 하면 통화 간격이 적어도 유지delay 됩니다. 또한 필요한 경우 루프를 쉽게 취소 setTimeout할 수 있습니다. 루프 종료 조건에 도달하면 호출하지 않습니다 .

더 나은 방법 은 함수를 생성하는 함수를 즉시 호출하는 함수 호출로 마무리 할 수 ​​있습니다 .

(function foo() {
    ...
    setTimeout(foo, delay);
})();

기능을 정의하고 사이클을 한 번에 시작합니다.


5
왜 선호 setTimeout합니까?
이상현

19
@Sangdol은 타이머 이벤트가 처리되지 않은 상태로 남아 있으면 타이머 스택이 "스택"되지 않도록하기 때문에 어떤 상황에서는 모든 setInterval이벤트가 지연없이 서로 바로 도착할 수 있습니다.
Alnitak

8
피곤할 때 스택에 올리지 못하게하는 일종의 테스트가 있어야합니다
James

3
방법을 사용하면 어떻게 기능을 중지 setTimeout합니까?
Gaurav Bhor

6
@DaveMunger 아니요, 실제로 재귀 적이 지 않기 때문에 "의사 재귀"뿐입니다. "재귀 적"호출은 브라우저가 이벤트 루프로 돌아올 때까지 발생하지 않습니다.이 시점에서 호출 스택이 완전히 풀립니다.
Alnitak

210

내가 당신을 올바르게 이해하고 있는지 확실하지 않지만 다음과 같이 쉽게 할 수 있습니다.

setInterval(function hello() {
  console.log('world');
  return hello;
}(), 5000);

이 작업을 수행하는 방법에는 여러 가지가 있지만 이것이 내가 생각할 수있는 가장 간결한 방법입니다.


16
이것은 즉시 실행되고 자체 반환되는 명명 된 함수이기 때문에 멋진 대답입니다. 정확히 내가 찾던 것.
jmort253

41
확실히 멋진 해결책이지만 앞으로 읽는 사람들에게 혼란을 줄 것입니다.
Deepak Joy

4
'hello'라는 이름을 지정할 필요가 없습니다. 대신 arguments.callee를 반환하고 익명 함수와 동일하게 사용할 수 있습니다
JochenJung

10
@JochenJung arguments.callee은 ES5 엄격 모드에서 사용할 수 없습니다
Alnitak

3
이것은 다른 언어에서 온 대부분의 새로운 JS 프로그래머를 혼동하는 일종의 Javascript 코드입니다. 회사에 JS 직원이 많지 않고 작업 보안을 원할 경우 이와 같이 많은 것을 작성하십시오.
Ian

13

나는 때문에 같은 문제로이 질문에 우연히하지만 당신이해야하는 경우에 대한 답변 중 어느 것도 도움이되지 정확히 행동을 같이 setInterval()하지만, 함께 에만 함수가 시작 부분에 즉시 호출된다는 차이.

이 문제에 대한 나의 해결책은 다음과 같습니다.

function setIntervalImmediately(func, interval) {
  func();
  return setInterval(func, interval);
}

이 솔루션의 장점 :

  • 기존 코드를 사용하여 setInterval쉽게 대체 할 수 있습니다.
  • 엄격한 모드에서 작동
  • 기존의 명명 된 함수 및 클로저와 함께 작동합니다.
  • 여전히 반환 값을 사용하여 clearInterval()나중에 전달할 수 있습니다

예:

// create 1 second interval with immediate execution
var myInterval = setIntervalImmediately( _ => {
        console.log('hello');
    }, 1000);

// clear interval after 4.5 seconds
setTimeout( _ => {
        clearInterval(myInterval);
    }, 4500);

건방진하려면 실제로 사용해야하는 경우 setInterval원본을 교체 할 수도 있습니다 setInterval. 따라서 기존 코드 앞에 추가 할 때 코드를 변경할 필요가 없습니다.

var setIntervalOrig = setInterval;

setInterval = function(func, interval) {
    func();
    return setIntervalOrig(func, interval);
}

그러나 위에 나열된 모든 장점은 여기에 적용되지만 대체 할 필요는 없습니다.


객체를 setTimeout반환하기 때문에 솔루션 보다이 솔루션을 선호 setInterval합니다. 어쩌면 나중에 코드에 따라서 정의되지 않은 현재 시간에있는 함수를 호출 방지하기 위해, 나는의 첫 번째 함수 호출을 래핑 setTimeout이 같은 기능을 setTimeout(function(){ func();},0);첫 번째 함수는 다음 또한 현재 처리주기, 후라고 즉시 , 그러나입니다 더 많은 오류가 입증되었습니다.
pensan

8

setInterval()해당 동작을 제공하는 함수를 래핑 할 수 있습니다.

function instantGratification( fn, delay ) {
    fn();
    setInterval( fn, delay );
}

... 다음과 같이 사용하십시오.

instantGratification( function() {
    console.log( 'invoked' );
}, 3000);

5
setInterval이 반환하는 것을 반환해야한다고 생각합니다. 그렇지 않으면 clearInterval을 사용할 수 없기 때문입니다.
Henrik R

5

필요한 경우 예쁘게 포장하는 래퍼가 있습니다.

(function() {
    var originalSetInterval = window.setInterval;

    window.setInterval = function(fn, delay, runImmediately) {
        if(runImmediately) fn();
        return originalSetInterval(fn, delay);
    };
})();

setInterval의 세 번째 인수를 true로 설정하면 setInterval을 호출 한 직후 처음으로 실행됩니다.

setInterval(function() { console.log("hello world"); }, 5000, true);

또는 세 번째 주장을 생략하면 원래 행동이 유지됩니다.

setInterval(function() { console.log("hello world"); }, 5000);

일부 브라우저는 이 랩퍼가 고려하지 않은 setInterval에 대한 추가 인수 를 지원 합니다. 나는 이것들이 거의 사용되지 않는다고 생각하지만, 필요할 때 명심하십시오.


9
사양이 변경되면 다른 공존 코드를 손상시킬 수 있으므로 기본 브라우저 기능을 재정의하는 것은 끔찍합니다. 사실, setInterval을 현재보다 매개 변수가 있습니다 developer.mozilla.org/en-US/docs/Web/API/WindowTimers/...
악셀 코스타스 페냐

2

누군가가 this화살표 기능 인 것처럼 외부를 가져와야합니다 .

(function f() {
    this.emit("...");
    setTimeout(f.bind(this), 1000);
}).bind(this)();

위의 가비지 생성이 귀찮 으면 대신 닫을 수 있습니다.

(that => {
    (function f() {
        that.emit("...");
        setTimeout(f, 1000);
    })();
})(this);

아니면 사용을 고려 장식 코드에 따라.@autobind


1

다음 순서로 함수를 호출하는 것이 좋습니다.

var _timer = setInterval(foo, delay, params);
foo(params)

특정 조건에서 _timer원하는 경우을 foo에 전달할 수도 clearInterval(_timer)있습니다.

var _timer = setInterval(function() { foo(_timer, params) }, delay);
foo(_timer, params);

더 자세히 설명해 주시겠습니까?
Polyducks

두 번째 호출에서 타이머를 설정했습니다. 처음으로 fn을 직접 호출하면됩니다.
Jayant Varshney

1

여기에 모든 혼란없이 초보자를위한 간단한 버전이 있습니다. 그냥 함수를 선언하고 호출 한 다음 간격을 시작합니다. 그게 다야.

//Declare your function here
function My_Function(){
  console.log("foo");
}    

//Call the function first
My_Function();

//Set the interval
var interval = window.setInterval( My_Function, 500 );


1
이것이 처음 몇 줄에서 허용되는 답변과 정확히 일치합니다. 이 답변은 새로운 것을 어떻게 추가합니까?
Dan Dascalescu

수락 된 대답은 이것을하지 말라고 계속합니다. 수락 된 답변에 대한 나의 답변은 왜 여전히 유효한 방법인지 설명합니다. OP는 구체적으로 첫 번째 호출에서 setInterval의 함수 호출을 요청하지만 허용되는 답변은 setTimeout의 이점에 대해 이야기합니다.
Polyducks

0

이 문제를 해결하기 위해 페이지가로드 된 후 처음으로 함수를 실행합니다.

function foo(){ ... }

window.onload = function() {
   foo();
};

window.setInterval(function()
{
    foo(); 
}, 5000);

0

firstInterval 이라는 편리한 npm 패키지가 있습니다 (전체 공개, 내 것).

여기서 많은 예제는 매개 변수 처리를 포함하지 않으며 setInterval대규모 프로젝트에서 기본 동작을 변경하는 것은 악의적입니다. 문서에서 :

이 패턴

setInterval(callback, 1000, p1, p2);
callback(p1, p2);

~와 동일하다

firstInterval(callback, 1000, p1, p2);

브라우저에서 구식이고 의존성을 원하지 않는 경우 코드 에서 쉽게 잘라 붙여 넣을 수 있습니다 .


0

// YCombinator
function anonymous(fnc) {
  return function() {
    fnc.apply(fnc, arguments);
    return fnc;
  }
}

// Invoking the first time:
setInterval(anonymous(function() {
  console.log("bar");
})(), 4000);

// Not invoking the first time:
setInterval(anonymous(function() {
  console.log("foo");
}), 4000);
// Or simple:
setInterval(function() {
  console.log("baz");
}, 4000);

자, 이것은 너무 복잡하므로 더 간단하게 설명하겠습니다.

function hello(status ) {    
  console.log('world', ++status.count);
  
  return status;
}

setInterval(hello, 5 * 1000, hello({ count: 0 }));


이것은 엄청나게 설계되었습니다.
Polyducks

0

초기 지연 시간 (예 : 100)을 매우 작게 설정하고 기능 내에서 원하는 지연 시간으로 설정할 수 있습니다.

var delay = 100;

function foo() {
  console.log("Change initial delay-time to what you want.");
  delay = 12000;
  setTimeout(foo, delay);
}


-2

표준 setTimeout / setInterval은 직접 0으로 설정하더라도 약 몇 밀리 초의 시간 초과를 갖기 때문에 함수의 즉각적인 비동기 호출에 문제가 있습니다. 브라우저 별 작업으로 인해 발생합니다.

Chrome, Safari, Opera에서 REAL 제로 지연 코드가있는 코드 예제

function setZeroTimeout(callback) {
var channel = new MessageChannel();
channel.port1.onmessage = callback;
channel.port2.postMessage('');
}

자세한 내용은 여기를 참조 하십시오

그리고 첫 번째 수동 호출 후 함수와의 간격을 만들 수 있습니다.


-10

실제로 가장 빠른 것은

interval = setInterval(myFunction(),45000)

이것은 myfunction을 호출 한 다음 45 초마다 agaian을 수행합니다.

interval = setInterval(myfunction, 45000)

전화하지는 않지만 예약 만


어디서 구했습니까?
Ken Sharp

2
이것은 myFunction()스스로 돌아 오는 경우에만 작동 합니다. 대신 호출하도록 각 함수를 수정 setInterval하는 것이 setInterval다른 답변에서 제안하는 것처럼 한 번 감싸는 것이 더 좋습니다 .
Jens Wirth
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.