setTimeout, setInterval and requestAnimationFrame
배워두면 인생에 도움이 되는 개념들이다.
먼저 setTimeout은 자바스크립트 개념에서 온 것이 아니다. 브라우저 그리고 nodeJS 개념에서 왔다.
이게 뭘 하는 것이냐? 시간이 조금 흐른후에 함수를 실행하는것을 해준다.
자세하게 설명을 하자면 setTimeout은 시간이 지난 후에 기능을 message queue에 붙여준다.
함수를 자동으로 부르는 것이 아니라 함수를 message queue에 넣고 stack이 비게되면 자바스크립트가 실행을 하는 개념인것이다.
바로 이뤄질수도 있고 자바스크립트가 바쁘면 천천히 할수도 있다. 그래서 time specific 하다고 볼 수 없다.
아래에서 보면 다음과 같이 작성을 할 것인데 작성하는 것을 보게 되면 다음과 같다.
첫번째 인자는 함수고 두번째 인자는 최소 대기 시간이 될것이다. 1초를 하도록 할 것이며 여기서 작성하는 것은 millisecond가 될것이다.
setTimeout(() => console.log("hi"), 1000) // 이걸 실행시키면 1초후에 hi를 얻게 될 것이다.
또한 이것은 다른 인자들도 갖고 있다. 이렇게 함수를 넣는 대신에 아래와 같이 입력할수도있다.
setTimeout( console.log, 1000, "Hi"); // 1초 후 Hi
setTimeout( console.log("hi"), 1000, "Hi"); // 이렇게 작성 x
알아 둬야할 것이 있는데 우리가 직접 함수를 부르지 않는다는 것이다. 함수를 setTimeout에게 주고 그 다음 setTimeout이 함수를 부르게 된다. 그렇게 때문에 이렇게 작성하진 않으며, 이렇게하면 바로 부를테니까 원하지 않는다.
그래서 그냥 함수 이름을 올려놓고 setTimeout이 함수를 부르게 할 것이다. 그리고 가끔은 취소하고 싶을때가 있다. 뭔가 hi라고 말하고 싶지 않을 때 10초 후에 이렇게 어떠한 이유에서든 이걸 취소하고 싶을때에는 setTimeout을 variable 안에 넣으면 된다.
const helloT = setTimeout(console.log, 10000, "Hello");
console.log(helloT); // 실행해보면 ID의 콘솔로그가 뜰 것이다. 우리 타임아웃의 ID인 것이다.
이것을 clearTimeout()을 사용하게 된다면?
const helloT = setTimeout(console.log, 10000, "Hello");
clearTimeout(helloT); // 타임아웃이 생성될때마다 ID가 리턴이 될것이며 이걸 저장하고 함수 cleartimeout을 실행 시킬것이다.
그리고 얻은 ID로 timeout을 정리하는 것이다. 만약 우리가 존재하지 않는 timeout을 정리하려고 하면 작동안할것이다.
const helloT = setTimeout(console.log, 10000, "Hello");
clearTimeout(8989898);
이렇게 쓴다고 해서 자바스크립트가 이건 존재하지 않아라고 알려주진 않는다. Timeout을 clear했지만 error가 생기지도 않는다.
여기까지가 timeout에 대한 내용이다. 기억해야할 건 이 숫자는 최소대기시간이라는 것이다. 이 함수를 Queue에 올리기까지 준비가 되면 자바스크립트가 부르는 형식이다. 확실한 시간은 아니며 지연이 될 수도 있다. 하지만 그리 큰 지연은 아니니 무시해도 된다.
그다음 컨셉은 setInterval인데 이건 정해진 매 시간마다 함수를 실행시키는 것이다.
const helloT = setInterval(console.log, 5000, "Hello");
작성 후 5초마다 함수를 실행이 될것이며 작성되는것을 볼 수 있으며 timeout과 동일한 인자와 함수를 가지고 있다는 것을 알 수 있다.
그러나 만약 interval이 1초보다 적다면 어떻게 될까? 크롬에서는 interval이 1초보다 짧다면 크롬은 그걸 1초로 맞춰버린다.
예를 들어 interval이 0.5초 였다면, user가 크롬 탭을 바꾸거나, 나가면 크롬은 그걸 1초로 바꿔버릴것이다. user가 설정한 값을 무시해 버릴 것이다. 또한 interval을 취소 할 수도 있다.
const helloT = setInterval(console.log, 5000, "Hello");
clearInterval(helloT);
그래서 정리를 하면 다음과 같다.
setTimeout : 몇초 기다린 후 함수를 실행하는 것
setInterval : 매 정해진 초마다 함수를 실행하는 것
참고로 함수를 실행하지말고, 함수의 이름을 넣도록해야한다. 그러면 setTimeout, setInterval이 대신 실행해 줄 것이다.
또한 timeout, Interval을 취소하고 싶다면 Clear를 사용하면 된다. 그리고 이걸 variable 로 저장하고 그래서 ID를 저장할 수 있도록 한다.
마지막으로 살펴볼것은 requestAnimationFrame이다.
여기서 animation을 알아보면 이전에는 스크린에서 뭔가 움직이게 하려면, 사람들은 setInterval을 사용했다. (5초마다 움직이는 설정)
그러나 Interval에 의지할 수 없고(Time specific이 아니기 때문이다) 또한, CPU, 그래픽카드가 느리면 Interval이 느려질 수 있다.
그래서 requestAnimationFrame이 나온것이며, 이건 함수를 실행하고 다시 브라우저를 칠하기 전에(이미지 렌더링을 뜻한다) 브라우저가 업데이트 할때마다 animation frame을 요청할 것이다. 그래서 animation을 수정할 수 있는 것이다.
만약 내가 animation 작업을 많이 하지 않는 이상 자주 쓸 일이 없을텐데 아래와 같이 callback은 브라우저 repaint 전에 호출 될것이다.
requestAnimationFrame(() => console.log("Hi"));
MDN에서 자세히 살펴보면 하나의 callback이 되며 타이밍이 필요없는것을 알 수 있다.
const sayHi = () => {
console.log("Hi");
requestAnimationFrame(sayHi);
};
requestAnimationFrame(sayHi);
이 함수 (say hi)를 아주 빠르게 실행할것이다. 참고로 이건 CPU, 그리고 그래픽카드에 최적화 되어있다. 예를 들어 내가 다른 탭으로 이동하게 되면, 크롬은 실행시키지 않을것이다. 해당 스크린을 페인트하는것이 아니기 때문이다.
뭔가를 최대한 빠르게 실행하고 싶다면 Request animation frame을 해봐!
'JavaScript > TIL' 카테고리의 다른 글
[TIL] #8. Message Queue and Event Loop (0) | 2020.08.17 |
---|---|
[TIL] #7. IIFE (0) | 2020.08.17 |
[TIL] #6. Expression vs. Statement (0) | 2020.08.17 |
[TIL] #5. Scope (0) | 2020.08.17 |
[TIL] #4. TYPE OF (0) | 2020.08.17 |