๋ธŒ๋ผ์šฐ์ €์˜ JavaScript ์ฝ”๋“œ ์‹คํ–‰ ๊ณผ์ • - ์ฝœ์Šคํƒ๊ณผ ์ด๋ฒคํŠธ ๋ฃจํ”„

์ฝœ์Šคํƒ (Call Stack)

์ฝœ์Šคํƒ์€ ํ˜„์žฌ ์‹คํ–‰ ์ค‘์ธ ํ•จ์ˆ˜์˜ ํ˜ธ์ถœ์„ ๊ธฐ๋กํ•˜๋Š” ์ž๋ฃŒ ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค. ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด ํ•ด๋‹น ํ•จ์ˆ˜์˜ ์ •๋ณด๊ฐ€ ์Šคํƒ์— ์ถ”๊ฐ€๋˜๊ณ , ํ•จ์ˆ˜์˜ ์‹คํ–‰์ด ์™„๋ฃŒ๋˜๋ฉด ์Šคํƒ์—์„œ ์ œ๊ฑฐ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ฝœ์Šคํƒ์€ ํ•จ์ˆ˜์˜ ํ˜ธ์ถœ ์ˆœ์„œ๋ฅผ ์ถ”์ ํ•˜๊ณ , ์‹คํ–‰ ์ค‘์ธ ํ•จ์ˆ˜์˜ ์ปจํ…์ŠคํŠธ๋ฅผ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ“ ์‹คํ–‰ ์ปจํ…์ŠคํŠธ๊ฐ€ ์ƒ์„ฑ๋˜๊ณ  ์ฝœ์Šคํƒ์— ์Œ“์ด๋Š” ๊ณผ์ •

function greet(name) {
  let greeting = "Hello, " + name + "!";
  console.log(greeting);
}

function sayHello() {
  greet("Alice");
}

sayHello();
  • 1. sayHello() ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด์„œ ์ƒˆ๋กœ์šด ์‹คํ–‰ ์ปจํ…์ŠคํŠธ๊ฐ€ ์ƒ์„ฑ๋˜๊ณ  ํ˜ธ์ถœ ์Šคํƒ์— ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค.
ใ€€ํ˜ธ์ถœ ์Šคํƒ: [sayHello()]
  • 2. sayHello() ํ•จ์ˆ˜ ๋‚ด์—์„œ greet("Alice")๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด์„œ ๋˜ ๋‹ค๋ฅธ ์‹คํ–‰ ์ปจํ…์ŠคํŠธ๊ฐ€ ์ƒ์„ฑ๋˜๊ณ  ํ˜ธ์ถœ ์Šคํƒ์— ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค.
ใ€€ํ˜ธ์ถœ ์Šคํƒ: [sayHello(), greet("Alice")]
  • 3. greet("Alice") ํ•จ์ˆ˜ ๋‚ด์—์„œ ๋ณ€์ˆ˜ greeting์ด ์ƒ์„ฑ๋˜๊ณ  ๊ฐ’์ด ํ• ๋‹น๋ฉ๋‹ˆ๋‹ค.
ใ€€ํ˜ธ์ถœ ์Šคํƒ: [sayHello(), greet("Alice")]
  • 4. console.log(greeting)์ด ์‹คํ–‰๋˜๊ณ  ํ˜ธ์ถœ ์Šคํƒ์—์„œ greet("Alice") ์‹คํ–‰ ์ปจํ…์ŠคํŠธ๊ฐ€ ์ œ๊ฑฐ๋ฉ๋‹ˆ๋‹ค.
ใ€€ํ˜ธ์ถœ ์Šคํƒ: [sayHello()]
  • 5. sayHello() ํ•จ์ˆ˜ ๋‚ด์˜ ๋ชจ๋“  ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋˜๊ณ  ํ˜ธ์ถœ ์Šคํƒ์—์„œ ํ•ด๋‹น ์‹คํ–‰ ์ปจํ…์ŠคํŠธ๊ฐ€ ์ œ๊ฑฐ๋ฉ๋‹ˆ๋‹ค.
ใ€€ํ˜ธ์ถœ ์Šคํƒ: []

์ด๋ฒคํŠธ ๋ฃจํ”„ ํ (Event Loop Queue)

์ด๋ฒคํŠธ ๋ฃจํ”„ ํ๋Š” ๋น„๋™๊ธฐ ์ž‘์—…์˜ ์™„๋ฃŒ ๋˜๋Š” ์ด๋ฒคํŠธ ๋ฐœ์ƒ์„ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๋Œ€๊ธฐ์—ด์ž…๋‹ˆ๋‹ค. ๋น„๋™๊ธฐ ํ•จ์ˆ˜์˜ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋‚˜ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ๊ธฐ๋Š” ์ด๋ฒคํŠธ ๋ฃจํ”„ ํ์— ์ถ”๊ฐ€๋˜์–ด ๋Œ€๊ธฐํ•˜๋‹ค๊ฐ€ ์ฝœ์Šคํƒ์ด ๋น„์–ด์žˆ์„ ๋•Œ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์ด๋ฒคํŠธ ๋ฃจํ”„๋Š” ์ฝœ์Šคํƒ์ด ๋น„์–ด์žˆ์„ ๋•Œ๋งˆ๋‹ค ํ์—์„œ ์ž‘์—…์„ ๊บผ๋‚ด์–ด ์ฝœ์Šคํƒ์— ์ถ”๊ฐ€ํ•˜์—ฌ ์‹คํ–‰๋  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ“ ์ด๋ฒคํŠธ ๋ฃจํ”„์™€ ํ˜ธ์ถœ ์Šคํƒ 1

setTimeout(() => {
  console.log('hello');
}, 0); // ์ž‘์—… ํ์— ์ฝœ๋ฐฑ์ด ์ถ”๊ฐ€๋จ

console.log('world');

// ์ถœ๋ ฅ ๊ฒฐ๊ณผ:
// world
// hello
1. setTimeout(() => { console.log('hello'); }, 0); ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.
  • setTimeout ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜์–ด ํƒ€์ด๋จธ๊ฐ€ ์„ค์ •๋ฉ๋‹ˆ๋‹ค. ์ด๋•Œ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋Š” ํƒœ์Šคํฌ ํ์— ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค.
  • ํ˜„์žฌ ํ˜ธ์ถœ ์Šคํƒ: [setTimeout()]
2. console.log('world'); ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.
  • "world"๊ฐ€ ์ฝ˜์†”์— ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค.
  • ํ˜„์žฌ ํ˜ธ์ถœ ์Šคํƒ: [setTimeout()]
3. ํ˜ธ์ถœ ์Šคํƒ์—์„œ๋Š” ๋” ์ด์ƒ ์‹คํ–‰ํ•  ์ฝ”๋“œ๊ฐ€ ์—†์œผ๋ฏ€๋กœ ์ด๋ฒคํŠธ ๋ฃจํ”„๊ฐ€ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.
4. ์ด๋ฒคํŠธ ๋ฃจํ”„๋Š” ํ˜ธ์ถœ ์Šคํƒ์ด ๋น„์–ด์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ , ๋น„์–ด์žˆ๋‹ค๋ฉด ์ž‘์—… ํ์— ์žˆ๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœ ์Šคํƒ์— ์ถ”๊ฐ€ํ•˜์—ฌ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
5. ์ž‘์—… ํ์— ์žˆ๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ ์Šคํƒ์— ์ถ”๊ฐ€๋˜์–ด ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.
  • "hello"๊ฐ€ ์ฝ˜์†”์— ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค.
  • ํ˜„์žฌ ํ˜ธ์ถœ ์Šคํƒ: []
์ด๋ ‡๊ฒŒ ๋˜๋ฉด "world"๊ฐ€ ๋จผ์ € ์ถœ๋ ฅ๋˜๊ณ , ๊ทธ ํ›„ "hello"๊ฐ€ ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” setTimeout์˜ ์‹œ๊ฐ„ ์ง€์—ฐ์ด 0ms๋กœ ์„ค์ •๋˜์—ˆ๋”๋ผ๋„, ํ•ด๋‹น ์ฝœ๋ฐฑ ํ•จ์ˆ˜๊ฐ€ ์ž‘์—… ํ์— ์ถ”๊ฐ€๋˜๊ณ  ์ด๋ฒคํŠธ ๋ฃจํ”„๋ฅผ ํ†ตํ•ด ํ˜ธ์ถœ ์Šคํƒ์— ์˜ฌ๋ผ๊ฐ€๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ JavaScript์˜ ๋น„๋™๊ธฐ์„ฑ์— ์˜ํ•ด ์ฝœ๋ฐฑ ํ•จ์ˆ˜์˜ ์‹คํ–‰์ด ์ด๋ฃจ์–ด์ง‘๋‹ˆ๋‹ค.

๐Ÿ“ ์ด๋ฒคํŠธ ๋ฃจํ”„์™€ ํ˜ธ์ถœ ์Šคํƒ 2

function greet(name) {
  let greeting = "Hello, " + name + "!";
  console.log(greeting);
}

function sayHello() {
  greet("Alice");
  setTimeout(function() {
    console.log("๋น„๋™๊ธฐ ํ•จ์ˆ˜ ์‹คํ–‰ ์™„๋ฃŒ");
  }, 1000); // 1์ดˆ ํ›„์— ์‹คํ–‰๋จ
}

sayHello();
  • 1. sayHello() ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด์„œ ์ƒˆ๋กœ์šด ์‹คํ–‰ ์ปจํ…์ŠคํŠธ๊ฐ€ ์ƒ์„ฑ๋˜๊ณ  ํ˜ธ์ถœ ์Šคํƒ์— ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค.
ใ€€ํ˜ธ์ถœ ์Šคํƒ: [sayHello()]
  • 2. sayHello() ํ•จ์ˆ˜ ๋‚ด์—์„œ greet("Alice")๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด์„œ ๋˜ ๋‹ค๋ฅธ ์‹คํ–‰ ์ปจํ…์ŠคํŠธ๊ฐ€ ์ƒ์„ฑ๋˜๊ณ  ํ˜ธ์ถœ ์Šคํƒ์— ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค.
ใ€€ํ˜ธ์ถœ ์Šคํƒ: [sayHello(), greet("Alice")]
  • 3. greet("Alice") ํ•จ์ˆ˜ ๋‚ด์—์„œ ๋ณ€์ˆ˜ greeting์ด ์ƒ์„ฑ๋˜๊ณ  ๊ฐ’์ด ํ• ๋‹น๋ฉ๋‹ˆ๋‹ค.
ใ€€ํ˜ธ์ถœ ์Šคํƒ: [sayHello(), greet("Alice")]
  • 4. console.log(greeting)์ด ์‹คํ–‰๋˜๊ณ  ํ˜ธ์ถœ ์Šคํƒ์—์„œ greet("Alice") ์‹คํ–‰ ์ปจํ…์ŠคํŠธ๊ฐ€ ์ œ๊ฑฐ๋ฉ๋‹ˆ๋‹ค.
ใ€€ํ˜ธ์ถœ ์Šคํƒ: [sayHello()]
  • 5. setTimeout ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜์–ด ํƒ€์ด๋จธ๊ฐ€ ์„ค์ •๋ฉ๋‹ˆ๋‹ค. ์ด๋•Œ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์‹คํ–‰๋˜๋ฏ€๋กœ ํ˜ธ์ถœ ์Šคํƒ์—๋Š” ์ถ”๊ฐ€๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
ใ€€ํ˜ธ์ถœ ์Šคํƒ:[sayHello()]
  • 6. sayHello() ํ•จ์ˆ˜ ๋‚ด์˜ ๋ชจ๋“  ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋˜์—ˆ์ง€๋งŒ, ์•„์ง ํƒ€์ด๋จธ๊ฐ€ ๋งŒ๋ฃŒ๋˜์ง€ ์•Š์•˜์œผ๋ฏ€๋กœ ์ด๋ฒคํŠธ ๋ฃจํ”„์—์„œ ๋Œ€๊ธฐํ•ฉ๋‹ˆ๋‹ค.
  • 7. 1์ดˆ ํ›„, ํƒ€์ด๋จธ๊ฐ€ ๋งŒ๋ฃŒ๋˜๋ฉด ์„ค์ •๋œ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๊ฐ€ ์ด๋ฒคํŠธ ๋ฃจํ”„ ํ์— ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค.
  • 8. ์ด๋ฒคํŠธ ๋ฃจํ”„๋Š” ํ˜ธ์ถœ ์Šคํƒ์ด ๋น„์–ด์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ , ๋น„์–ด์žˆ๋‹ค๋ฉด ์ด๋ฒคํŠธ ๋ฃจํ”„ ํ์—์„œ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ๊บผ๋‚ด์™€ ํ˜ธ์ถœ ์Šคํƒ์— ์ถ”๊ฐ€ํ•˜์—ฌ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  • 9. ๋น„๋™๊ธฐ ํ•จ์ˆ˜ ์‹คํ–‰ ์™„๋ฃŒ" ๋ฉ”์‹œ์ง€๊ฐ€ ์ถœ๋ ฅ๋˜๊ณ  ํ˜ธ์ถœ ์Šคํƒ์—์„œ ํ•ด๋‹น ์‹คํ–‰ ์ปจํ…์ŠคํŠธ๊ฐ€ ์ œ๊ฑฐ๋ฉ๋‹ˆ๋‹ค.
ใ€€ํ˜ธ์ถœ ์Šคํƒ: []
์ด๋ ‡๊ฒŒ ๋น„๋™๊ธฐ ํ•จ์ˆ˜๊ฐ€ ์ถ”๊ฐ€๋˜๋ฉด, ํ•ด๋‹น ๋น„๋™๊ธฐ ํ•จ์ˆ˜์˜ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๊ฐ€ ์ด๋ฒคํŠธ ๋ฃจํ”„๋ฅผ ํ†ตํ•ด ์ ์ ˆํ•œ ์‹œ์ ์— ํ˜ธ์ถœ๋˜์–ด ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

JavaScript ์ฝ”๋“œ ์‹คํ–‰์ด ๋ธŒ๋ผ์šฐ์ €์˜ ์„ฑ๋Šฅ๊ณผ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์— ๋ฏธ์น˜๋Š” ์˜ํ–ฅ

์›น ๋ธŒ๋ผ์šฐ์ €๋Š” ์ฝœ ์Šคํƒ์— ์‹คํ–‰ ์ปจํ…์ŠคํŠธ๊ฐ€ ์กด์žฌํ•˜๋Š” ๋™์•ˆ, ์ฆ‰ ์‹คํ–‰ ์ค‘์ธ ํ•จ์ˆ˜๊ฐ€ ์กด์žฌํ•˜๋Š” ๋™์•ˆ์—๋Š” ๋จนํ†ต์ด ๋˜์–ด ๋ฒ„๋ฆฝ๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €๋Š” ๋Œ€๊ฐœ 60fps๋กœ ๋™์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ๋Œ€๋žต 16ms ์•ˆ์— ์ฝ”๋“œ์˜ ์‹คํ–‰์„ ์™„๋ฃŒํ•˜์ง€ ๋ชปํ•˜๋ฉด ๋ธŒ๋ผ์šฐ์ €์˜ ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ๋š๋š ๋Š๊ธฐ๋Š” ํ˜„์ƒ์ด ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์— ์•…์˜ํ–ฅ์„ ๋ฏธ์น  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// ๋™๊ธฐ์ ์ธ ์ฒ˜๋ฆฌ ์˜ˆ์ œ
function syncExample() {
  console.log("์‹œ์ž‘");
  for (let i = 0; i < 1000000000; i++) {
    // ๋งค์šฐ ์˜ค๋žœ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฌ๋Š” ์ž‘์—…
  }
  console.log("์ข…๋ฃŒ");
}

// ๋น„๋™๊ธฐ์ ์ธ ์ฒ˜๋ฆฌ ์˜ˆ์ œ
function asyncExample() {
  console.log("์‹œ์ž‘");
  setTimeout(function() {
    console.log("๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ์™„๋ฃŒ");
  }, 2000); // 2์ดˆ ํ›„์— ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ์‹คํ–‰
  console.log("์ข…๋ฃŒ");
}

// ๋™๊ธฐ์ ์ธ ์ฒ˜๋ฆฌ ์‹คํ–‰
syncExample();

// ๋น„๋™๊ธฐ์ ์ธ ์ฒ˜๋ฆฌ ์‹คํ–‰
asyncExample();

        
์œ„ ์ฝ”๋“œ์—์„œ syncExample ํ•จ์ˆ˜๋Š” ๋งค์šฐ ์˜ค๋žœ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฌ๋Š” ๋ฐ˜๋ณต๋ฌธ์„ ํฌํ•จํ•˜๊ณ  ์žˆ์–ด, ์‹คํ–‰ ์ค‘์—๋Š” ๋‹ค๋ฅธ ์ž‘์—…์ด ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ด ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰ ์ค‘์ผ ๋•Œ๋Š” ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋จนํ†ต์ด ๋˜์–ด ๋ฒ„๋ฆฌ๊ณ , ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ๋Š๊ฒจ ๋ณด์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

asyncExample ํ•จ์ˆ˜๋Š” ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค. setTimeout ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๋„๋ก ํ•˜์˜€๊ธฐ ๋•Œ๋ฌธ์—, ์ด ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋˜๋Š” ๋™์•ˆ์—๋„ ๋‹ค๋ฅธ ์ž‘์—…์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋š๋š ๋Š๊ธฐ๋Š” ํ˜„์ƒ์„ ๋ฐฉ์ง€ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ, ๋น„๋™๊ธฐ์ ์ธ ์ฒ˜๋ฆฌ๋ฅผ ํ†ตํ•ด ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋จนํ†ต์ด ๋˜๋Š” ํ˜„์ƒ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.