โฑ ์๋ฐ์คํฌ๋ฆฝํธ ๋น๋๊ธฐ ์ฒ๋ฆฌ (setTimeout)
// 1๋ฒ
let num = 1;
// 2๋ฒ
setTimeout(() => {
num = 2;
}, 0);
// 3๋ฒ
num = 3;
console.log(num);
์ ์ฝ๋๋ฅผ ์คํํ๋ฉด console.log(num)
์ ๋ฌด์์ ์ถ๋ ฅํ ๊น?
console.log(num) // 3
๊ฒฐ๊ณผ๋ 3์ด ์ถ๋ ฅ๋๋ค.
๊ทธ ์ด์ ๋ setTimeout
์ด ๋น๋๊ธฐ ํจ์์ด๊ธฐ ๋๋ฌธ์ด๋ค.
โ๏ธ setTimeout ์คํ ํ๋ฆ
1. ๋๊ธฐ์ฝ๋
- ์ฝ ์คํ(Call Stack)์ ๋ค์ด๊ฐ ์ฆ์ ์คํ๋๋ค.
- 1๋ฒ (
let num = 1
), 3๋ฒ (num = 3
),console.log(num)
์ด ์์๋๋ก ์ฝ ์คํ์ ๋ค์ด๊ฐ์ ์คํ๋๋ค.
2. ๋น๋๊ธฐ ์ฝ๋
setTimeout
๊ฐ์ ๋น๋๊ธฐ ํจ์๋ ํธ์ถ๋๋ฉด ์ ๊น ์คํ์ ์ฌ๋ผ์๋ค๊ฐ, ๋ฐ๋ก Web APIs ์์ญ์ผ๋ก ์ ๋ฌ๋๋ค.- Web APIs๋ ๋ ๋ฒ์งธ ์ธ์๋ก ๋ฐ์ ์๊ฐ์ด ์ง๋๋ฉด,
setTimeout
์ ์ฝ๋ฐฑ ํจ์๋ฅผ Callback Queue(Task Queue)๋ก ๋ณด๋ธ๋ค.
3. ์ด๋ฒคํธ ๋ฃจํ
- ์ด๋ฒคํธ ๋ฃจํ(Event Loop)๋ ์ฝ ์คํ์ด ๋น์ด ์๋์ง ๊ณ์ ํ์ธํ๋ค.
- ์ฝ ์คํ์ด ๋น๋ฉด, ํ์คํฌ ํ์ ์์ธ ์ฝ๋ฐฑ ํจ์๋ฅผ ์ฝ ์คํ์ผ๋ก ์ฎ๊ฒจ์ ์คํํ๋ค.
๋ฐ๋ผ์ setTimeout
์ ์ฝ๋ฐฑ ํจ์๋ console.log(num)
์ด ์คํ๋ ์ดํ์ ์ฝ ์คํ์ ๋ค์ด์ฌ ์ ์๋ค.
๊ทธ๋์ ์ถ๋ ฅ๋๋ ๊ฐ์ 2
๊ฐ ์๋๋ผ 3
์ด๋ค.
๐ async/await
console.log("1");
async function getData() {
// await #1
const res = await fetch("https://jsonplaceholder.typicode.com/todos/1");
// await #2
const data = await res.json();
console.log("2", data.title);
}
getData();
console.log("3");
์ ์ฝ๋๋ ๋น๋๊ธฐ ์ฝ๋์ธ async ํจ์ ์์ ์ด๋ค.
์ฝ๋๋ฅผ ์คํํ๋ฉด ์ถ๋ ฅ ๊ฒฐ๊ณผ๋ ์๋์ ๊ฐ๋ค.
1
3
2 delectus aut autem
โ๏ธ async/await ์คํ ํ๋ฆ
1. ๋๊ธฐ ์ฝ๋
console.log("1")
์คํ →1
์ถ๋ ฅ- ๋๊ธฐ ์ฝ๋์ด๋ฏ๋ก ๋ฐ๋ก ์ฝ ์คํ์์ ์ฒ๋ฆฌ๋๋ค.
2. async ํจ์ ์ง์
getData()
๊ฐ ํธ์ถ๋๋ค.- ๋ด๋ถ์์
fetch(...)
์คํ → ๋คํธ์ํฌ ์์ฒญ์ Web APIs๋ก ๋์ด๊ฐ๋ค. - ๋์์
fetch
๋Promise { <pending> }
์ ๋ฐํํ๋ค. await
๋ฅผ ๋ง๋๋ฉดgetData
ํจ์๋ ์ผ์ ์ค๋จ๋๊ณ ,fetch Promise
๊ฐfulfilled
๋ ๋ await์ ๋ค์ ์ค์ธconst data = await res.json();
์ด ๋ง์ดํฌ๋กํ์คํฌ๋ก ์์ฝ๋๋ค.
3. ๋๊ธฐ ์ฝ๋ ๊ณ์ ์คํ
- ์ฝ ์คํ์ด ๋น์์ผ๋ฏ๋ก, ๋ฐ๊นฅ์ ์๋
console.log("3")
์คํ →3
์ถ๋ ฅ
4. ๋คํธ์ํฌ ์๋ต (fetch ์๋ฃ ~ ๊ทธ ์ดํ)
- ๋คํธ์ํฌ ์๋ต์ด ์๋ฃ๋๋ฉด
Promise
๊ฐ fulfilled ์ํ๊ฐ ๋๋ค. - ์ด๋ ์์ฝํด ๋์๋ ์ฝ๋๊ฐ ๋ง์ดํฌ๋กํ์คํฌ ํ์ ์ ๋ฌ๋๋ค.
- ํ์ ์ ๋ฌ๋ ์ฝ๋๋ฅผ ์ด๋ฒคํธ ๋ฃจํ๊ฐ ์ฝ ์คํ์ผ๋ก ์ฎ๊ฒจ์ ์ฝ๋๋ฅผ ์คํํ๋ค.
res.json()
๋Promise { <pending> }
์ ๋ฐํํ๋ค.- ๋ค์
await
๋ฅผ ๋ง๋์ ๊ทธ ์๋ ์ฝ๋(console.log("2", data.title)
)๋ ๋ ๋ฒ์งธ ๋ง์ดํฌ๋กํ์คํฌ๋ก ์์ฝ๋๋ค. res.json()
์ดfulfilled
๋๋ฉดconsole.log(”2”, data.title)
๋ ๋ง์ดํฌ๋กํ์คํฌ ํ์ ์ ๋ฌ๋๊ณ ์ด๋ฒคํธ ๋ฃจํ๊ฐ ์ฝ์คํ์ ์ ๋ฌํด์ ์คํํ๋ค.
โ๏ธ setTimeout๊ณผ Promise์ ์ฐจ์ด์
setTimeout
์ ์ฝ๋ฐฑ → Task Queue(๋งคํฌ๋กํ์คํฌ ํ)์ ๋ค์ด๊ฐ๋ค.Promise
์then
๊ณผawait, async
→ Microtask Queue(์กํ)์ ๋ค์ด๊ฐ๋ค.
์ด๋ฒคํธ ๋ฃจํ๋ ํญ์ ๋ง์ดํฌ๋กํ์คํฌ ํ๋ฅผ ๋จผ์ ์ฒ๋ฆฌํ๊ธฐ ๋๋ฌธ์,
๊ฐ์ ์กฐ๊ฑด์ด๋ผ๋ฉด Promise
์ ์ฝ๋ฐฑ์ด setTimeout
๋ณด๋ค ๋จผ์ ์คํ๋๋ค.
console.log("start");
setTimeout(() => {
console.log("setTimeout");
}, 0);
Promise.resolve().then(() => {
console.log("promise");
});
console.log("end");
์ ์ฝ๋๋ฅผ ์คํํ๋ฉด ๋ค์๊ณผ ๊ฐ์ด ์ถ๋ ฅ๋๋ค.
start
end
promise
setTimeout
๐ก ํ์คํฌ ํ์ ๋ง์ดํฌ๋กํ์คํฌ ํ ๋น๊ต
๊ตฌ๋ถ | ํ์คํฌ ํ (๋งคํฌ๋กํ์คํฌ ํ) | ๋ง์ดํฌ๋กํ์คํฌ ํ (์ก ํ) |
---|---|---|
์ฃผ์ ํญ๋ชฉ | setTimeout , setInterval , addEventListener , XMLHttpRequest ์ด๋ฒคํธ ๋ฑ |
Promise ์ .then , .catch , .finally ์ฝ๋ฐฑ ํจ์, async/await |
์ฐ์ ์์ | ๋ฎ์ | ๋์ |
์คํ ์์ | ๋ง์ดํฌ๋กํ์คํฌ ํ๊ฐ ๋ชจ๋ ๋น์์ง ํ, ํ์์ ํ๋์ฉ ๊บผ๋ด์ด ์คํ | ํ์ฌ ์คํ ์ค์ธ ๋๊ธฐ ์ฝ๋๊ฐ ์ข ๋ฃ๋ ์งํ, ํ๊ฐ ๋ชจ๋ ๋น ๋๊น์ง ์ ๋ถ ์คํ |
๐ ์ฐธ๊ณ
๋ชจ๋ ์๋ฐ์คํฌ๋ฆฝํธ Deep Dive
http://latentflip.com/loupe/?code=JC5vbignYnV0dG9uJywgJ2NsaWNrJywgZnVuY3Rpb24gb25DbGljaygpIHsKICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gdGltZXIoKSB7CiAgICAgICAgY29uc29sZS5sb2coJ1lvdSBjbGlja2VkIHRoZSBidXR0b24hJyk7ICAgIAogICAgfSwgMjAwMCk7Cn0pOwoKY29uc29sZS5sb2coIkhpISIpOwoKc2V0VGltZW91dChmdW5jdGlvbiB0aW1lb3V0KCkgewogICAgY29uc29sZS5sb2coIkNsaWNrIHRoZSBidXR0b24hIik7Cn0sIDUwMDApOwoKY29uc29sZS5sb2coIldlbGNvbWUgdG8gbG91cGUuIik7%21%21%21
latentflip.com