Scheduling: setTimeout and setInterval - Lee-hyuna/33-js-concepts-kr GitHub Wiki
๋ฒ์ญ : https://javascript.info/settimeout-setinterval#canceling-with-cleartimeout
์ฐ๋ฆฌ๋ ํจ์๊ฐ ์ฆ์ ์คํํ์ง ์๊ณ ํน์ ์๊ฐ์ ์คํ๋๊ธธ ๊ฒฐ์ ํ ์ ์๋ค. ์ด๊ฒ์ "scheduling a call" ์ด๋ผ ๋ถ๋ฆฝ๋๋ค.
์ฌ๊ธฐ ๋๊ฐ์ง ๋ฉ์๋๊ฐ ์์ต๋๋ค.
-
setTimeout
์ด๊ฒ์ ํน์ ์๊ฐ ๊ฐ๊ฒฉ ํ์ ํ๋ฒ ์คํ๋ฉ๋๋ค. -
setInterval
์ด๊ฒ์ ํน์ ์๊ฐ ๊ฐ๊ฒฉ๋์ ์ฃผ๊ธฐ์ ์ผ๋ก ์คํ๋ฉ๋๋ค.
์ด ๋ฉ์๋๋ค์ ์๋ฐ์คํฌ๋ฆฝํธ์ ํน์ ํญ๋ชฉ์ ํ ํํธ๊ฐ ์๋๋๋ค. ํ์ง๋ง ๋๋ถ๋ถ ํ๊ฒฝ๋ค์ ๋ด๋ถ์ ์ธ ์ค์ผ์ฅด๋ฌ๋ฅผ ๊ฐ์ง๊ณ ์๊ณ ์ด๋ฐ ๋ฉ์๋๋ค์ ์ ๊ณตํ๊ณ ์์ต๋๋ค. ํนํ๋ ์ด๋ค์ ๋ชจ๋ ๋ธ๋ผ์ฐ์ ์ Node.js์์ ์ง์์ ํ๊ณ ์์ต๋๋ค.
๋ฌธ๋ฒ
let timerId = setTimeout(func|code, [delay], [arg1], [arg2], ...)
ํ๋ผ๋ฏธํฐ๋ค:
func|code
ํจ์ ๋๋ ์ฝ๋๋ญ์น๋ค์ ์คํํฉ๋๋ค. ๋๊ฒ๋ ํจ์์ ๋๋ค. ์ญ์ฌ์ ์ธ ์ด์ ๋ก ์ธํด ์ผ๋ จ์ ์ฝ๋๋ฅผ ์ ๋ฌํ ์๋ ์์ง๋ง ๊ถ์ฅํ์ง๋ ์์ต๋๋ค.
delay
๋์ํ๊ธฐ ์ ๋๋ ์ด ์๊ฐ์ ๋๋ค. ๋จ์๋ ๋ฐ๋ฆฌ์ธ์ปจ๋(1000ms = 1 ์ด), ๋ํดํธ๋ 0
arg1
, arg2
โฆ
ํจ์์ ์ ๋ฌ๋ ์ธ์๋ค ( IE9 ๋ ์ง์์ ํ์ง ์์ต๋๋ค. )
์๋ฅผ ๋ค๋ฉด sayHi()
๋ผ๋ ์ฝ๋๋ฅผ 1์ด ๋ค์ ํธ์ถํ ๊ฒ์
๋๋ค.
function sayHi() {
alert('Hello');
}
setTimeout(sayHi, 1000);
์ธ์๋ค๊ณผ ํจ๊ป ํธ์ถํ๋ ค๋ฉด
function sayHi(phrase, who) {
alert( phrase + ', ' + who );
}
setTimeout(sayHi, 1000, "Hello", "John"); // Hello, John
๋ง์ฝ์ ์ฒซ๋ฒ์งธ ์ธ์๋ก ๋ฌธ์์ด์ ๋๊ธด๋ค๋ฉด ์๋ฐ์คํฌ๋ฆฝํธ๋ ์ด ๋ฌธ์์ด์ ๊ฐ์ง๊ณ ํจ์๋ฅผ ๋ง๋ญ๋๋ค.
์ด๋ ๊ฒ ์๋๋ ์ ์์ต๋๋ค.
setTimeout("alert('Hello')", 1000);
ํ์ง๋ง ๋ฌธ์์ด์ ์ฌ์ฉํ๋๊ฒ์ ์ถ์ฒํ์ง ์์ต๋๋ค. ๊ทธ๊ฒ ๋์ ์ ์๋์ฒ๋ผ ํจ์๋ฅผ ์ฌ์ฉํ์ญ์์.
setTimeout(() => alert('Hello'), 1000);
์ด๋ณด์ ๊ฐ๋ฐ์๋ค์ด ๋๋๋ก ํจ์๋ฅผ ๋๊ฒผ๋๋ฐ ์๋ํ์ง ์๋ ์ค์๋ฅผ ๋ฒํ ๋๊ฐ ์์ต๋๋ค. ํจ์๋ฅผ ๋๊ธฐ๋ฉด์ ๊ดํธ() ๋ฅผ ํจ๊ป ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
// wrong!
setTimeout(sayHi(), 1000);
์ด๊ฒ์ ์๋ํ์ง ์์ต๋๋ค. setTimeout
์ ํจ์์ ๋ ํผ๋ฐ์ค๋ฅผ ๊ธฐ๋ ํฉ๋๋ค.
์ฌ๊ธฐ์ sayHi()
๋ฅผ ์คํํ๊ณ ๊ทธ ์คํ์ ๊ฒฐ๊ณผ๋ฅผ setTimeout
์ ์ธ์๋ก ๋๊น๋๋ค.
์ฌ๊ธฐ ์ฐ๋ฆฌ์ ๊ฒฝ์ฐ์๋ sayHi()
๋ undefined
(ํจ์๊ฐ ์๋ฌด๊ฒ๋ ๋ฐํํ์ง ์์๋ค.) ๋ฅผ ๋ฐํํด์ ์๋ฌด๊ฒ๋ ์ค์ผ์ฅด๋ง ๋์ง ์์ต๋๋ค.
setTimeout
์ "timer identifier" ๋ผ๋ ๊ฒ์ ๋ฐํํฉ๋๋ค. ์ด timerId
๋ ์คํ์ ์ทจ์ํ ์ ์์ต๋๋ค.
์ทจ์ ๋ฌธ๋ฒ:
let timerId = setTimeout(...);
clearTimeout(timerId);
์๋ ์ฝ๋์์ ๋ณด๋ฉด, ์ฐ๋ฆฌ๋ ํจ์ํ๋๋ฅผ ์ค์ผ์ฅด ํ๊ณ ๊ทธ ํ์ ์ทจ์ํ์ต๋๋ค.(๋ง์์ด ๋ฐ๋์ด์) ๊ทธ ๊ฒฐ๊ณผ ์๋ฌด์ผ๋ ์ผ์ด๋์ง ์์ต๋๋ค.
let timerId = setTimeout(() => alert("never happens"), 1000);
alert(timerId); // timer identifier
clearTimeout(timerId);
alert(timerId); // same identifier (doesn't become null after canceling)
์ฐ๋ฆฌ๋ alert์ output์ผ๋ก๋ถํฐ ๋ณผ์ ์์ต๋๋ค. ๋ธ๋ผ์ฐ์ timer identifier๋ ์ซ์ ์ ๋๋ค. ๋ค๋ฅธ ํ๊ฒฝ์์๋ ์ด๊ฒ์ ๋ฌด์์ธ๊ฐ ๋ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค๋ฉด Node.js์์๋ ์ถ๊ฐ์ ์ธ ๋ฉ์๋๋ฅผ ์ง๋ timer ๊ฐ์ฒด๋ฅผ ๋ฆฌํดํ๊ฒ ๋ฉ๋๋ค.
๋ค์๋งํด ์ด ๋ฉ์๋๋ค์ ์ ๋๋ฒ์ ํ ๋ช ์ธ๊ฐ ์์ต๋๋ค. ๊ทธ๋๋ ๊ด์ฐฎ์ต๋๋ค. ๋ธ๋ผ์ฐ์ ๋ค์ timer๋ค์ HTML5 ํ์ค์ timers section์์ ์ค๋ช ํ๊ณ ์์ต๋๋ค.
setInterval
๋ฉ์๋๋ setItmeout
๊ณผ ๋์ผํ ๋ฌธ๋ฒ์ ์ง๋๊ณ ์์ต๋๋ค.
let timerId = setInterval(func|code, [delay], [arg1], [arg2], ...)
๋ชจ๋ ์ธ์๊ฐ๋ค์ ๊ฐ์ ์๋ฏธ๋ฅผ ์ง๋๊ณ ์์ต๋๋ค. ํ์ง๋ง setTimeout
๊ณผ๋ฅธ ๋ค๋ฅด๊ฒ ๊ทธ๊ฒ์ ํจ์๋ฅผ ํ๋ฒ๋ง ๋์์ํค์ง ์์ต๋๋ค. ์๊ฐ์ ๊ฐ๊ฒฉ์ด ์ฃผ์ด์ง๋ฉด ๊ท์น์ ์ผ๋ก ์คํํ๊ฒ ๋ฉ๋๋ค.
์ถ๊ฐ์ ์ธ ํธ์ถ์ ๋ง์ผ๋ ค๋ฉด, ์ฐ๋ฆฐ clearInterval(timerId)
๋ฅผ ํธ์ถํด์ผ ํฉ๋๋ค.
๋ค์ ์์ ์๋ ๋งค 2์ด๋ง๋ค ๋ฉ์ธ์ง๋ฅผ ๋ณด์ฌ์ฃผ๋ ์์ ์ ๋๋ค. 5์ด ํ์ output์ด ๋ฉ์ถ๊ฒ ๋ฉ๋๋ค.
// repeat with the interval of 2 seconds
let timerId = setInterval(() => alert('tick'), 2000);
// after 5 seconds stop
setTimeout(() => { clearInterval(timerId); alert('stop'); }, 5000);
๊ฒฝ๊ณ ์ฐฝ์ด ๋ณด์ฌ์ง๋ ๋์์๋ ์๊ฐ์ ๊ฐ๋๋ค.
ํฌ๋กฌ๊ณผ ํ์ด์ดํญ์ค๋ฅผ ํฌํจํ๋ ๋๋ถ๋ถ์ ๋ธ๋ผ์ฐ์ ๋ค์ alert/confirm/prompt
๊ฐ ๋ณด์ฌ์ง๋ ๋์ ๋ด๋ถ์ ์ธ timer ๊ฐ ๊ณ์ "๋๋ฑ"(์งํ๋๋ค) ๋ฉ๋๋ค.
๊ทธ๋์ ๋ง์ฝ ์ ์ฝ๋๋ฅผ ์คํํ๊ณ ๋์ ๋ช๋ช์๊ฐ ๋์ alert
์ฐฝ์ ๋ซ์ง ์๋๋ค๋ฉด, ๋ค์ ํ์๋ฅผ ํ์๋ง์ alert์ฐฝ์ ์ฆ์ ๋ณด์ฌ์ค๊ฒ์
๋๋ค. ์ค์ alert๋ค์ ์ฌ์ด ๊ฐ๊ฒฉ์ 5์ด ๋ณด๋ค๋ ๋ ์งง์ ๊ฒ์
๋๋ค.
๊ท์น์ ์ผ๋ก ๋ญ๊ฐ๋ฅผ ์คํ์ 2๊ฐ์ง ๋ฐฉ๋ฒ์ด ์์ต๋๋ค.
setInterval
์ด ํ๊ฐ์ง์ด๊ณ ๋ค๋ฅธ ํ๊ฐ์ง๋ ์ฌ๊ท์ ์ธ setTimeout
์
๋๋ค.
/** instead of:
let timerId = setInterval(() => alert('tick'), 2000);
*/
let timerId = setTimeout(function tick() {
alert('tick');
timerId = setTimeout(tick, 2000); // (*)
}, 2000);
setTimeout
์ (*) ์ด ๋ถ๋ถ์์๋ ํ์ฌ ํธ์ถ์ ๋์์ ๋ฐ๋ก ๋ค์ ํธ์ถ์ ์์ฝํฉ๋๋ค.
์ฌ๊ท์ ์ธ setTimeout
์ setInterval
๋ณด๋ค ์ข ๋ ์ ์ฐํฉ๋๋ค. ์ด๋ ๊ฒํ๋ฉด ๋ค์ ํธ์ถ์ด ํ์ฌ ํธ์ถ์ ๊ฒฐ๊ณผ์ ๋ฐ๋ผ ๋ค๋ฅด๊ฒ ์ค์ผ์ค ๋ ์ ์์ต๋๋ค.
์๋ฅผ ๋ค๋ฉด, ์ฐ๋ฆฌ๋ ๋งค 5์ด๋ง๋ค ์๋ฒ์ ์์ฒญํ๋ ์๋น์ค๋ฅผ ๊ธฐ๋กํด์ผ ํฉ๋๋ค. ํ์ง๋ง ์ง๋์น๊ฒ ๋ถํ๊ฐ ๊ฑธ๋ฆฌ๋ ์๋ฒ์ ๊ฒฝ์ฐ์๋ ์ด ๊ฐ๊ฒฉ์ 10, 20, 40์ด๋ก ๋๋ ค์ผ ํฉ๋๋ค.
์ฌ๊ธฐ ์๋ ์ฝ๋๋ฅผ ๋ณด์ญ์์
let delay = 5000;
let timerId = setTimeout(function request() {
...send request...
if (request failed due to server overload) {
// increase the interval to the next run
delay *= 2;
}
timerId = setTimeout(request, delay);
}, delay);
๊ทธ๋ฆฌ๊ณ ์ฐ๋ฆฌ๊ฐ ๊ณํํ๊ณ ์๋ ๊ธฐ๋ฅ์ด CPU ์ฌ์ฉ์ด ๋ง์ ๊ฒฝ์ฐ, ์คํ์ ๊ฑธ๋ฆฐ ์๊ฐ์ ์ธก์ ํ๊ณ ์กฐ๋ง๊ฐ ๋ค์ ํธ์ถ์ ๊ณํ ํ ์ ์์ต๋๋ค.
์ฌ๊ท์ ์ธ setTimeout
์ ์คํ ์ฌ์ด์ ์ง์ฐ์ ๋ณด์ฅํ์ง๋ง, setInterval
์ ๊ทธ๋ ์ง ๋ชปํฉ๋๋ค.
์ฌ๊ธฐ ๋๊ฐ์ง์ ์ฝ๋ ์กฐ๊ฐ์ด ์์ต๋๋ค. ์ฒ์์ setInterval
์ฌ์ฉ์
๋๋ค.
let i = 1;
setInterval(function() {
func(i);
}, 100);
๋๋ฒ์งธ ๊ฒฝ์ฐ๋ ์ฌ๊ท์ ์ธ setTimeout
์ฌ์ฉ์
๋๋ค.
let i = 1;
setTimeout(function run() {
func(i);
setTimeout(run, 100);
}, 100);
setInterval
์ ๋ด๋ถ์ ์ธ ์ค์ผ์ฅด๋ง์ func(i)
๋ฅผ ๋งค 100ms ๋ง๋ค ์คํํฉ๋๋ค.
๋ณด์ด์๋์?
setInterval
๋ก ํจ์ func()
ํธ์ถ๋๋ ์ค์ ๋๋ ์ด๊ฐ๊ฒฉ์ ์ฝ๋์์์ ๋ณด๋๊ฑฐ๋ณด๋ค ํจ์ฌ ๋ํ๋ค.
func
์ ์คํ๋ interval์ ํ ๋ถ๋ถ์ผ๋ก ์๊ฐ์ด ์๋น๋๊ธฐ ๋๋ฌธ์ด๋ค.
์ด๊ฒ์ func
์ ์คํ์ด ์ฐ๋ฆฌ๊ฐ ๊ธฐ๋ํ๊ณ ์ฃผ์ด์ง 100ms ์ด๋ณด๋ค ๋ ๊ธธ์ด์ง์ ์์ต๋๋ค.
์ด ๊ฒฝ์ฐ ์์ง์ func
์ด ์๋ฃ ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฐ ๋ค์ ์ค์ผ์ค๋ฌ๋ฅผ ๊ฒ์ฌํ๊ณ ์๊ฐ์ด ๋๋๋ฉด ์ฆ์ ๋ค์ ์คํํฉ๋๋ค.
๋๋ฌธ ๊ฒฝ์ฐ๋ก, ํจ์๊ฐ ํญ์ ์ง์ฐ ms๋ณด๋ค ์ค๋ ์คํ๋๋ฉด ํธ์ถ์ ์ผ์ ์ค์ง์์ด ๋ฐ์ํฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ ์ฌ๊ธฐ ์ฌ๊ท์ ์ธ setTimeout
์ ๊ทธ๋ฆผ์ด ์์ต๋๋ค.
์ฌ๊ท setTimeout์ ๊ณ ์ ์ง์ฐ (์ฌ๊ธฐ์๋ 100ms)์ ๋ณด์ฅํฉ๋๋ค.
์๋ก์ด ์ฝ์ ์ด์ ์ ์์ ์ด ๋๋๊ณ ๊ณํ๋๊ธฐ ๋๋ฌธ์ ๋๋ค.
ํจ์๋ฅผ setInterval/setTimeout
์ ๋๊ธธ๋, ๋ด๋ถ ์ฐธ์กฐ๊ฐ ํจ์์์ ์๊ฒจ๋๊ณ ์ค์ผ์ฅด๋ฌ ์์ ์ ์ฅ๋ฉ๋๋ค. ์ด๊ฒ์ garbage collected ๋ก ๋ถํฐ ํจ์๋ฅผ ์ง์ผ๋ด๋๋ฐ ์ฌ์ง์ด ๋ค๋ฅธ ์ฐธ์กฐ๊ฐ์๋ ๊ฒฝ์ฐ์๋ ๋ง์ฐฌ๊ฐ์ง์
๋๋ค.
// the function stays in memory until the scheduler calls it
setTimeout(function() {...}, 100);
setInterval
์ ๊ฒฝ์ฐ์๋ clearInterval
์ด ํธ์ถ ๋ ๋๊น์ง ๋ฉ๋ชจ๋ฆฌ์ ๋จ์์๊ฒ ๋ฉ๋๋ค.
์ด๊ฒ์ ๋ถ์์ฉ์ด ์์ต๋๋ค. ํจ์๋ ์ธ๋ถ lexical ํ๊ฒฝ์ ์ฐธ์กฐํฉ๋๋ค. ๊ทธ๋์ ์ด ํจ์๊ฐ ์ด์์๋ ๋์, ์ธ๋ถ ๋ณ์๋ค ๋ํ ์ด์์๊ฒ ๋ฉ๋๋ค. ๊ทธ๊ฒ๋ค์ ํจ์ ์์ฒด๋ณด๋ค ๋๋ง์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฐจ์ง ํ ์ ์์ต๋๋ค. ๊ทธ๋์ ๋์ด์ ํจ์ ์ค์ผ์ฅด๋ง์ด ํ์์์ ๋์๋ ์ทจ์ํ๋๊ฒ ์ข์ต๋๋ค. ๊ทธ๊ฒ์ด ์์ ํจ์๋ผ๋ ๋ง์ ๋๋ค.
์ฌ๊ธฐ ์์ฃผ ํน๋ณํ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค.: setTimeout(func, 0)
, ๋๋ setTimeout(func)
.
์ด func
์ ์คํ ์ค์ผ์ฅด์ ๊ณง ๊ฐ๋ฅํฉ๋๋ค. ๊ทธ๋ฌ๋ ์ค์ผ์ฅด๋ฌ๋ ์ค์ง ํ์ฌ ์ฝ๋๊ฐ ๋ค ์๋ฃ ๋ ์ดํ์ ์คํ์ ์ํต๋๋ค.
๊ทธ๋์ ํจ์๋ ํ์ฌ ์ฝ๋๊ฐ ๋ค ์คํ๋ ์ดํ์ ๋์ํ๋ผ๊ณ ์ค์ผ์ฅด ๋ฉ๋๋ค. ๋ค์ ๋งํด์ ๋น๋๊ธฐ์ ์ธ ๊ฒ์
๋๋ค.
์๋ฅผ๋ค์ด ์ด ๊ฒฐ๊ณผ๋ "Hello" ๋์ค๊ณ ๋์ ์ฆ์ "World"๊ฐ ๋์ฌ๊ฒ๋๋ค.
setTimeout(() => alert("World"));
alert("Hello");
์ฒซ ๋ฒ์งธ ๋ผ์ธ์ "0ms ํ์ ํด๋น ์คํ์ ์บ๋ฆฐ๋์ ๋ฃ์ต๋๋ค." ๊ทธ๋ฌ๋ ์ค์ผ์ค๋ฌ๋ ํ์ฌ ์ฝ๋๊ฐ ์๋ฃ๋ ํ์ ๋ง โโ"์บ๋ฆฐ๋๋ฅผ ํ์ธ"ํ๋ฏ๋ก "Hello"๊ฐ ๋จผ์ ์ค๊ณ "World"๊ฐ ๋ค์์ต๋๋ค.
์ฌ๊ธฐ CPU-hungry(cpu ์์์ ๋ง์ด ๋จน๋) ์ํ์ setTimeout
์ ์ฌ์ฉํด์ ๋ถ๋ฆฌ์ํค๋ ํธ๋ฆญ์ด ์์ต๋๋ค.
์๋ฅผ ๋ค์ด ๊ตฌ๋ฌธ ๊ฐ์กฐ ํ์ ์คํฌ๋ฆฝํธ (์ด ํ์ด์ง์ ์ฝ๋ ์์ ๋ฅผ ์์น ํ๋ ๋ฐ ์ฌ์ฉ)๋ CPU๊ฐ ๋ง์ด ์๋ชจ๋ฉ๋๋ค. ์ฝ๋๋ฅผ ๊ฐ์กฐ ํ์ํ๊ธฐ ์ํด ๋ถ์์ ์ํํ๊ณ , ๋ง์ ์์ ์์๋ฅผ ๋ง๋ค๊ณ , ๋ฌธ์์ ์ถ๊ฐํฉ๋๋ค. ๋ธ๋ผ์ฐ์ ๊ฐ "๋ฉ์ถ๋"๊ฒฝ์ฐ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ์ด๋ ๋ฐ์ ๋ค์ผ ์ ์์ต๋๋ค.
๊ทธ๋์ ์ฐ๋ฆฌ๋ ๊ธด ํ
์คํธ๋ฅผ ์กฐ๊ฐ๋ค๋ก ๋๋ ์ ์์ต๋๋ค. ์ฒ์์ผ๋ก 100 ๋ผ์ธ์ ์์ฑํ ๋ค์setTimeout (..., 0)
์ ์ฌ์ฉํ์ฌ ๋ ๋ค๋ฅธ 100 ๋ผ์ธ์ ๊ณํํ์ญ์์ค.
๋ช ํ์ฑ์ ์ํด๋ณด๋ค ๊ฐ๋จํ ์์ ๋ฅผ ๊ณ ๋ คํด ๋ณด๊ฒ ์ต๋๋ค. '1'์์ '1000000000'๊น์ง ๊ณ์ฐํ๋ ๊ธฐ๋ฅ์ด ์์ต๋๋ค.
์คํํ๋ฉด CPU๊ฐ ๋ฉ์ถฅ๋๋ค. ๋ถ๋ช ํ ๋์ ๋๋ ์๋ฒ ์ธก JS์ ๊ฒฝ์ฐ์ ๋ธ๋ผ์ฐ์ ์์ ์ด ์ฝ๋๋ฅผ ์คํ ์ํจํ์ ํ์ด์ง์ ๋ค๋ฅธ ๋ฒํผ์ ํด๋ฆญ์ ์๋ํด๋ด๋ผ. ์ ์ฒด JavaScript๊ฐ ์ค์ ๋ก ์ผ์ ์ค์ง ๋ ๊ฒ์ ํ์ธํ ์ ์์ผ๋ฉฐ ์๋ฃ ๋ ๋๊น์ง๋ ๋ค๋ฅธ ์์ ์ ์ํ ํ ์ ์์ต๋๋ค.
let i = 0;
let start = Date.now();
function count() {
// do a heavy job
for (let j = 0; j < 1e9; j++) {
i++;
}
alert("Done in " + (Date.now() - start) + 'ms');
}
count();
๋ธ๋ผ์ฐ์ ๋ "์คํฌ๋ฆฝํธ๊ฐ ๋๋ฌด ์ค๋ ๊ฑธ๋ฆฐ๋ค"๋ผ๋ ๊ฒฝ๊ณ ๋ฅผ ํ์ ํ ์๋ ์์ต๋๋ค (๊ทธ๋ฌ๋ ์ซ์๊ฐ ๊ทธ๋ฆฌ ํฌ์ง ์๊ธฐ ๋๋ฌธ์ ์๋์ง ์์ต๋๋ค.)
์ค์ฒฉ ๋ setTimeout์ ์ฌ์ฉํ์ฌ ์์ ์ ๋ถํ ํฉ์๋ค.
let i = 0;
let start = Date.now();
function count() {
// do a piece of the heavy job (*)
do {
i++;
} while (i % 1e6 != 0);
if (i == 1e9) {
alert("Done in " + (Date.now() - start) + 'ms');
} else {
setTimeout(count); // schedule the new call (**)
}
}
count();
์ด์ ๋ธ๋ผ์ฐ์ UI๋ "๊ณ์ฐ ์ค"ํ๋ก์ธ์ค์์ ์๋ฒฝํ๊ฒ ์๋ํฉ๋๋ค.
(*)
๋ก ํ์๋ ๋ถ๋ถ์ ๋์์ ๋ณด์:
- ์ฒ์ ๋์ :
i=1...1000000
. - ๋๋ฒ์งธ ๋์ :
i=1000001..2000000
- ๊ทธ๋ฆฌ๊ณค ๊ณ์..,
while
์i
๊ฐ1000000
์ผ๋ก ๊ท ๋ฑํ๊ฒ ๋ถํ ๋๋์ง ๊ฒ์ฌํฉ๋๋ค.
(**)
ํ์ ๋ ๊ณณ์์ ์์ง ์์
์ด ์๋ฃ๊ฐ ๋์ง ์์๋ค๋ฉด ๋ค์ ํธ์ถ์ ์ค์ผ์ฅด๋ง์ ํฉ๋๋ค.
์นด์ดํธ ์คํ ์ฌ์ด์ ์ผ์ ์ค์ง๋ ์๋ฐ ์คํฌ๋ฆฝํธ ์์ง์ด ๋ค๋ฅธ ์์ ์ ์ํํ๊ณ ๋ค๋ฅธ ์ฌ์ฉ์ ์์ ์ ๋ฐ์ ํ ์์์๋งํผ ์ถฉ๋ถํ "ํธํก"์ ์ ๊ณตํฉ๋๋ค.
์ฃผ๋ชฉํ ๋งํ ์ ์ setTimeout์ผ๋ก ์์ ์ ๋ถํ ํ๊ฑฐ๋ ๋ถํ ํ์ง ์์ ๋ ๊ฐ์ง ์ํฉ ๋ชจ๋ ์๋๊ฐ ๋น์ทํ๋ค๋ ์ ์ ๋๋ค. ์ ์ฒด ๊ณ์ฐ ์๊ฐ์๋ ๋ณ๋ค๋ฅธ ์ฐจ์ด๊ฐ ์์ต๋๋ค.
๊ทธ๊ฒ๋ค์ ๋ ๊ฐ๊น๊ฒ ๋ง๋ค๊ธฐ ์ํด์, ๊ฐ์ ํด ๋ณด๊ฒ ์ต๋๋ค.
count ()์ ์์ ๋ถ๋ถ์ ์ค์ผ์ฅด๋ง์ผ๋ก ์ด๋์ํค๊ฒ ์ต๋๋ค.
let i = 0;
let start = Date.now();
function count() {
// move the scheduling at the beginning
if (i < 1e9 - 1e6) {
setTimeout(count); // schedule the new call
}
do {
i++;
} while (i % 1e6 != 0);
if (i == 1e9) {
alert("Done in " + (Date.now() - start) + 'ms');
}
}
count();
์ด์ ์ฐ๋ฆฌ๊ฐcount ()
๋ฅผ ์์ํ๊ณ ๋ ๋ง์ ๊ฒ์ count ()
ํ ํ์๊ฐ ์์์ ์๊ฒ๋๋ฉด, ์์
์ ์ํํ๊ธฐ ์ ์ ์ฆ์ ๊ทธ๊ฒ์ ๊ณํํฉ๋๋ค.
์คํํ๋ฉด ํจ์ฌ ์ ์ ์๊ฐ์ด ๊ฑธ๋ฆฌ๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.
๋ธ๋ผ์ฐ์ ์๋ ์ค์ฒฉ ํ์ด๋จธ๋ฅผ ์คํํ ์์๋ ๋น๋์ ํ๊ณ๊ฐ ์์ต๋๋ค. HTML5 ํ์ค์ ๋ฐ๋ฅด๋ฉด "5 ๊ฐ์ ์ค์ฒฉ ๋ ํ์ด๋จธ ์ดํ์ ๊ฐ๊ฒฉ์ ์ต์ 4 ๋ฐ๋ฆฌ ์ด๊ฐ๋์ด์ผํฉ๋๋ค."
์๋ ์๋ฅผ ํตํด ์๋ฏธ๋ฅผ ์ค๋ช ํด ๋ณด๊ฒ ์ต๋๋ค. ๊ทธ๊ฒ์ setTimeout ํธ์ถ์ 0ms ํ์ ์ค์ค๋ก๋ฅผ ์ฌ ์ค์ผ์ฅด ํฉ๋๋ค. ๊ฐ ํธ์ถ์ times ๋ฐฐ์ด์ ์ด์ ํธ์ถ๋ก๋ถํฐ ์ค์๊ฐ์ ๊ธฐ์ตํฉ๋๋ค. ์ค์ ์ง์ฐ์ ์ด๋ป๊ฒ ์๊ฒผ์ต๋๊น? ๋ด ์๋ค :
let start = Date.now();
let times = [];
setTimeout(function run() {
times.push(Date.now() - start); // remember delay from the previous call
if (start + 100 < Date.now()) alert(times); // show the delays after 100ms
else setTimeout(run); // else re-schedule
});
// an example of the output:
// 1,1,1,1,9,15,20,24,30,35,40,45,50,55,59,64,70,75,80,85,90,95,100
์ฒซ ๋ฒ์งธ ํ์ด๋จธ๋ ์ฆ์ ์คํ๋๋ฉฐ (์ฌ์๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก) ์ง์ฐ์ด ๋ฐ์ํ๊ณ 9, 15, 20, 24๊ฐ ํ์๋ฉ๋๋ค.
๊ทธ๋ฌํ ์ ํ์ ๊ณ ๋๋ถํฐ ์์ผ๋ฉฐ ๋ง์ ์คํฌ๋ฆฝํธ๊ฐ์ด ์คํฌ๋ฆฝํธ๋ฅผ ์ฌ์ฉํ๋ฏ๋ก ์ญ์ฌ์ ์ธ ์ด์ ๋ก ์กด์ฌํฉ๋๋ค.
์๋ฒ ์ธก JavaScript์ ๊ฒฝ์ฐ ์ด๋ฌํ ์ ํ์ด ์กด์ฌํ์ง ์์ผ๋ฉฐ Node.js์ process.nextTick ๋ฐ setImmediate์ ๊ฐ์ ์ฆ๊ฐ์ ์ธ ๋น๋๊ธฐ ์์ ์ ์์ฝํ๋ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค. ๋ฐ๋ผ์์ด ๊ฐ๋ ์ ๋ธ๋ผ์ฐ์ ๋ง๋ค ๋ค๋ฆ ๋๋ค.
๋ธ๋ผ์ฐ์ ์คํฌ๋ฆฝํธ์ ๋ง์ ์์ ์ ๋๋๋ ๋ ๋ค๋ฅธ ์ด์ ์ ์ฌ์ฉ์์๊ฒ ์งํ๋ฅ ๋ง๋ ๋๋ ๋ฌด์ธ๊ฐ๋ฅผ ํ์ ํ ์ ์๋ค๋ ๊ฒ์ ๋๋ค.
์ผ๋ฐ์ ์ผ๋ก ๋ธ๋ผ์ฐ์ ๋ ํ์ฌ ์คํ์ค์ธ ์ฝ๋๊ฐ ์๋ฃ๋ ํ ๋ชจ๋ "๋ค์ ๊ทธ๋ฆฌ๊ธฐ"๋ฅผ ์ํํฉ๋๋ค. ๋ฐ๋ผ์ ๋ง์ ์์๋ฅผ ๋ณ๊ฒฝํ๋ ํ๋์ ๊ฑฐ๋ํ ํจ์๋ฅผ ์ํํ๋ฉด ๋ณ๊ฒฝ ์ฌํญ์ด ์๋ฃ ๋ ๋๊น์ง ๋ณ๊ฒฝ๋์ง ์์ต๋๋ค.
๋ฐ๋ชจ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
<div id="progress"></div>
<script>
let i = 0;
function count() {
for (let j = 0; j < 1e6; j++) {
i++;
// put the current i into the <div>
// (we'll talk about innerHTML in the specific chapter, it just writes into element here)
progress.innerHTML = i;
}
}
count();
</script>
๊ทธ๊ฒ์ ์คํํ๋ฉด ์ ์ฒด ์นด์ดํธ๊ฐ ๋๋ ํ์ i์ ๋ํ ๋ณ๊ฒฝ ์ฌํญ์ด ํ์๋ฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ setTimeout์ ์ฌ์ฉํ์ฌ ์กฐ๊ฐ์ผ๋ก ๋ถํ ํ๋ฉด ๋ณ๊ฒฝ ์ฌํญ์ด ์คํ ์ฌ์ด์ ์ ์ฉ๋๋ฏ๋ก ๋ ์ ๋ณด์ ๋๋ค.
<div id="progress"></div>
<script>
let i = 0;
function count() {
// do a piece of the heavy job (*)
do {
i++;
progress.innerHTML = i;
} while (i % 1e3 != 0);
if (i < 1e9) {
setTimeout(count);
}
}
count();
</script>
์ด์
-setInterval (func, delay, ... args)
๋ฉ์๋์setTimeout (func, delay, ... args)
๋ฉ์๋๋func
๋ฅผdelay
๋ฐ๋ฆฌ ์ธ์ปจ๋ ํ์ ์ ๊ธฐ์ ์ผ๋ก / ํ๋ฒ ์คํํ๋๋ก ํ์ฉํ๋ค.
- ์คํ์ ์ทจ์ํ๋ ค๋ฉด
setInterval / setTimeout
์ ์ํด ๋ฐํ ๋ ๊ฐ์ผ๋กclearInterval / clearTimeout
์ ํธ์ถํด์ผํฉ๋๋ค. - ์ค์ฒฉ ๋
setTimeout
ํธ์ถ์setInterval
์ ๋ํ๋ณด๋ค ์ ์ฐํ ๋์์ ๋๋ค. ๋ํ ๊ทธ๋ค์ ์ฌํ ์งํ ๋์ ์ต์ํ์ ์๊ฐ์ ๋ณด์ฅ ํ ์ ์์ต๋๋ค. - ์ ๋ก ํ์ ์์ ์ค์ผ์ฅด๋ง
setTimeout (func, 0)
(setTimeout (func)
๊ณผ ๋์ผ)์ "๊ฐ๋ฅํ ํ ๋นจ๋ฆฌ, ๊ทธ๋ฌ๋ ํ์ฌ ์ฝ๋๊ฐ ์๋ฃ๋ ํ์"ํธ์ถ์ ์ค์ผ์ฅดํ๋๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
setTimeout (func)
์ ๋ช ๊ฐ์ง ์ฌ์ฉ ์ผ์ด์ค :
- CPU๊ฐ ๋ง์ด ์ฌ์ฉ๋๋ ์์ ์ ์ฌ๋ฌ ์กฐ๊ฐ์ผ๋ก ๋๋์ด ์คํฌ๋ฆฝํธ๊ฐ "์ ์ง"ํ์ง ์๋๋ก ํ๊ธฐ.
- ํ๋ก์ธ์ค๊ฐ ์งํ๋๋ ๋์ ๋ธ๋ผ์ฐ์ ๊ฐ ๋ค๋ฅธ ์์ ์ ์ํํ๊ฒ ๋๋๋ก ํ๊ธฐ (์งํ๋ฅ ๋ง๋๋ฅผ ๊ทธ๋ฆฝ๋๋ค).
๋ชจ๋ ์ค์ผ์ค๋ง ๋ฐฉ๋ฒ์ ์ ํํ ์ง์ฐ์ ๋ณด์ฅํ์ง ์์ต๋๋ค. ์ฐ๋ฆฌ๋ ์์ ๋ ์ฝ๋์ ์์กดํด์๋ ์๋ฉ๋๋ค.
์๋ฅผ ๋ค์ด, ๋ธ๋ผ์ฐ์ ๋ด๋ถ ํ์ด๋จธ๊ฐ ์ฌ๋ฌ ๊ฐ์ง ์ด์ ๋ก ๋๋ ค์ง ์ ์์ต๋๋ค.
- CPU์ ๊ณผ๋ถํ๊ฐ ์์ต๋๋ค.
- ๋ธ๋ผ์ฐ์ ํญ์ด ๋ฐฑ๊ทธ๋ผ์ด๋ ๋ชจ๋์ ์์ต๋๋ค.
- ๋ ธํธ๋ถ์ด ๋ฐฐํฐ๋ฆฌ๋ก ์๋ํฉ๋๋ค.
์ต์ํ ๋ธ๋ผ์ฐ์ ์ ์ค์ ์ ๋ฐ๋ผ ์ต์ ํ์ด๋จธ ํด์๋ (์ต์ ์ง์ฐ ์๊ฐ)๋ฅผ 300ms ๋๋ 1000ms๊น์ง ๋์ด๋ ์ ์์ต๋๋ค.