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.