์ƒ์„ธ ์ปจํ…์ธ 

๋ณธ๋ฌธ ์ œ๋ชฉ

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐœ๋ฐœ์ž๋ผ๋ฉด ์•Œ์•„์•ผํ•˜๋Š” ํ•ต์‹ฌ 33๊ฐœ ์ด๋ก  | #1. Call Stack

๋ณธ๋ฌธ

๋ฐ˜์‘ํ˜•

https://github.com/leonardomso/33-js-concepts

 

GitHub - leonardomso/33-js-concepts: ๐Ÿ“œ 33 JavaScript concepts every developer should know.

๐Ÿ“œ 33 JavaScript concepts every developer should know. - GitHub - leonardomso/33-js-concepts: ๐Ÿ“œ 33 JavaScript concepts every developer should know.

github.com

 

์•„๋ž˜ ๊ทธ๋ฆผ์€ Javasript Concurrency Model(V8 ์—”์ง„)์œผ๋กœ์จ sing call stack, heap, queue๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. 

 

1. Heap

๊ฐ์ฒด๋“ค์€ ๋Œ€๋ถ€๋ถ„์€ ๋ฉ”๋ชจ๋ฆฌ์˜ ๊ตฌ์กฐํ™”๋˜์ง€ ์•Š์€ ์˜์—ญ๊ณผ ๊ฐ™์€ heap์— ์œ„์น˜ํ•˜๋Š”๋ฐ, 
๋ณ€์ˆ˜๋‚˜ ๊ฐ์ฒด๋“ค์— ๋Œ€ํ•œ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์ด ์ด๊ณณ์—์„œ ์ผ์–ด ๋‚ฉ๋‹ˆ๋‹ค.

 

2. Queue

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋Ÿฐํƒ€์ž„์€ ์ฒ˜๋ฆฌํ•  message ๋ชฉ๋ก, ์‹คํ–‰ ๊ด€๋ จ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๊ฐ€ ํฌํ•จ๋œ message queue๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.
์Šคํƒ์ด ์ถฉ๋ถ„ํ•œ ์šฉ๋Ÿ‰์ด ์žˆ์„ ๋•Œ, ๋ฉ”์‹œ์ง€๋ฅผ ํ์—์„œ ๊บผ๋‚ด์„œ ๊ด€๋ จ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ง„ํ–‰์‹œํ‚ค๊ณ (์ด๋ ‡๊ฒŒ ์ดˆ๊ธฐ์˜ ์Šคํƒ ํ”„๋ ˆ์ž„์„ ๋งŒ๋“ ๋‹ค), ์Šคํƒ์ด ๋‹ค์‹œ ๋น„์–ด์ง€๋ฉด ๋ฉ”์‹œ์ง€ ์ฒ˜๋ฆฌ๊ฐ€ ์ข…๋ฃŒ๋ฉ๋‹ˆ๋‹ค.
๊ธฐ๋ณธ ์šฉ์–ด๋กœ, ์ด๋Ÿฐ ๋ฉ”์‹œ์ง€๋“ค์ด ์™ธ๋ถ€ ๋น„๋™๊ธฐ ์ด๋ฒคํŠธ๋“ค์— ๋Œ€ํ•œ ์‘๋‹ต, ์ฝœ๋ฐฑ ํ•จ์ˆ˜๊ฐ€ ์ œ๊ณต๋œ ๊ฒฝ์šฐ์— ๋Œ€ํ•ด ํ์ž…๋‹ˆ๋‹ค.(๋งˆ์šฐ์Šค ํด๋ฆญ๋จ, HTTP request์˜ ์‘๋‹ต ์ˆ˜์‹ )
์˜ˆ๋ฅผ ๋“ค์–ด, ์‚ฌ์šฉ์ž๊ฐ€ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๊ณ  ์ฝœ๋ฐฑ ํ•จ์ˆ˜๊ฐ€ ์—†๋‹ค๋ฉด ์–ด๋–ค message๋„ enqueue๋˜์ง€ ์•Š์•˜์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

3. Call Stack

Call Stack์€ ์—ฌ๋Ÿฌ ํ•จ์ˆ˜๋“ค(functions)์„ ํ˜ธ์ถœํ•˜๋Š” ์Šคํฌ๋ฆฝํŠธ์—์„œ ํ•ด๋‹น ์œ„์น˜๋ฅผ ์ถ”์ ํ•˜๋Š” ์ธํ„ฐํ”„๋ฆฌํ„ฐ (์›น ๋ธŒ๋ผ์šฐ์ €์˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ธํ„ฐํ”„๋ฆฌํ„ฐ๊ฐ™์€)๋ฅผ ์œ„ํ•œ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ž…๋‹ˆ๋‹ค. ํ˜„์žฌ ์–ด๋–ค ํ•จ์ˆ˜๊ฐ€ ๋™์ž‘ํ•˜๊ณ  ์žˆ๋Š”์ง€, ๊ทธ ํ•จ์ˆ˜ ๋‚ด์—์„œ ์–ด๋–ค ํ•จ์ˆ˜๊ฐ€ ๋™์ž‘ํ•˜๋Š” ์ง€, ๋‹ค์Œ์— ์–ด๋–ค ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜์–ด์•ผํ•˜๋Š” ์ง€ ๋“ฑ์„ ์ œ์–ดํ•ฉ๋‹ˆ๋‹ค.

 

์ฆ‰ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์‹คํ–‰ํ•ด์•ผ ํ•˜๋Š” ํ•จ์ˆ˜๋Š” ์Šคํƒ(stack)์— ์˜ฌ๋ผ๊ฐ€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ์„ ์–ธ๋œ ํ•จ์ˆ˜๋“ค์€ ์Šคํƒ ์œ„์— push๋กœ ์˜ฌ๋ ค ๋†“๊ณ  ์ฐจ๋ก€๋กœ ํ•จ์ˆ˜๋ฅผ ๋‹ค ์‹คํ–‰ํ•˜๋ฉด pop์œผ๋กœ ์ œ๊ฑฐ๋ฉ๋‹ˆ๋‹ค.

๊ทธ๋ ‡๊ฒŒ ์ฝœ์Šคํƒ์˜ ํ•จ์ˆ˜๋“ค์ด ๋‹ค ์‹คํ–‰๋˜์–ด  ๋‹ค ์ œ๊ฑฐ๋˜๋ฉด ํ”„๋กœ๊ทธ๋žจ์€ ์ข…๋ฃŒ๋˜๊ฒŒ ๋˜์ฃ .

์Šคํƒ๊ตฌ์กฐ

์˜ˆ๋ฅผ ๋“ค์–ด...

function foo(b) {
  var a = 5;
  return a * b + 10;
}

function bar(x) {
  var y = 3;
  return foo(x * y);
}

console.log(bar(6));

ํ•ด๋‹น ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด...

์ฝœ์Šคํƒ์€ ์•„๋ž˜ gif์˜์ƒ์ฒ˜๋Ÿผ ์‹คํ–‰๋  ๋•Œ๋งˆ๋‹ค Call Stack์— ํ•˜๋‚˜์”ฉ ์Œ“์ด๊ฒŒ ๋˜๊ณ , ์ฝœ์Šคํƒ์— ์Œ“์ธ console.log์™€ bar, foo ํ•จ์ˆ˜๊ฐ€ ์ฐจ๋ก€๋กœ ์‹คํ–‰ ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌํ„ดํ•จ๊ณผ ๋™์‹œ์— pop๋˜์–ด Call Stack์—์„œ ์‚ฌ๋ผ์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. 

 

 

๊ทธ๋ฆฌ๊ณ  ๋งŒ์•ฝ ์•„๋ž˜ ๊ทธ๋ฆผ์ฒ˜๋Ÿผ foo ํ•จ์ˆ˜์—์„œ ๊ฐ•์ œ๋กœ ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋ฉด stack trace๋ฅผ ์ฝ˜์†”์—์„œ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๊ทธ๋ฆผ์ฒ˜๋Ÿผ ์—๋Ÿฌ๋Š” ํ˜„์žฌ ์ฝœ์Šคํƒ์˜ ์ƒํƒœ๋ฅผ ๋‚˜ํƒ€๋‚ด์ฃผ๊ณ  ํ•จ์ˆ˜์•ˆ์—์„œ ์Šคํƒ๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์œ„์—์„œ ์•„๋ž˜์˜ ์ด๋™์ด ์‹คํŒจํ•œ ๊ฒƒ์„ ๋ณด์—ฌ์ฃผ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

 

๋”ฐ๋ผ์„œ Call Stack์„ ํ†ตํ•ด ํ•จ์ˆ˜์˜ ์‹คํ–‰์ˆœ์„œ๋ฅผ ํ™•์ธํ•˜๊ณ  ์ถ”์ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

๋ฌผ๋ก  ํ•จ์ˆ˜๋ฅผ ๋ฐ˜๋ณตํ•ด์„œ ๋ฌดํ•œ ํ˜ธ์ถœํ•˜๊ฒŒ ๋˜๋ฉด ์ œํ•œ๋œ ์Šคํ…์‚ฌ์ด์ฆˆ๋กœ ์ธํ•ด Max Stack Error Reached๋กœ throw ์—๋Ÿฌ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ ์ž…๋‹ˆ๋‹ค.

 

 

์ผ๋ฐ˜์ ์ธ ์ด๋ฒคํŠธ ๋ฃจํ”„

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ™˜๊ฒฝ์—์„œ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ–ˆ์„๋•Œ Call Stack, Event Loop, ๊ทธ๋ฆฌ๊ณ  Web APIs๊ฐ€ ์–ด๋–ค ์‹์œผ๋กœ ๋™์ž‘ํ•˜๋Š”์ง€ ์‚ดํŽด๋ณด๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค.

 

์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด..

setTimeout(() => { 
  console.log('hi')
}, 1000)

 

์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋˜๋ฉด..

ํ•ด๋‹น ์‚ฌ์‹ค์„ Call Stack์— (์—ฌ๊ธฐ์„œ๋Š” <global>) ํ‘ธ์‹œํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

        [code]        |   [call stack]    | [Event Loop] | |   [Web APIs]  |
  --------------------|-------------------|--------------| |---------------|
  setTimeout(() => {  | <global>          |              | |               |
    console.log('hi') |                   |              | |               |
  }, 1000)            |                   |              | |               |
                      |                   |              | |               |

๊ทธ๋ฆฌ๊ณ ๋‚˜์„œ ์ฝ”๋“œ์˜ ์ฒซ๋ฒˆ์งธ ๋ผ์ธ์„ ์‹คํ–‰์‹œํ‚ค๊ธฐ ์œ„ํ•ด setTimeout ํ•จ์ˆ˜๊ฐ€ Call Stack์— ๋‘๋ฒˆ์งธ ํ•ญ๋ชฉ์œผ๋กœ ๋“ค์–ด(ํ‘ธ์‹œ)๊ฐ‘๋‹ˆ๋‹ค.

        [code]        |   [call stack]    | [Event Loop] | |   [Web APIs]  |
  --------------------|-------------------|--------------| |---------------|
> setTimeout(() => {  | <global>          |              | |               |
    console.log('hi') | setTimeout        |              | |               |
  }, 1000)            |                   |              | |               |
                      |                   |              | |               |

setTimeout์„ ์‹คํ–‰ํ•˜๋ฉด JS๊ฐ€ ์•„๋‹Œ ์ฝ”๋“œ๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. setTimeout์€ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์šฐ๋ฆฌ์—๊ฒŒ ์ œ๊ณตํ•˜๋Š” ์›น API์˜ ์ผ๋ถ€์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

        [code]        |   [call stack]    | [Event Loop] | |   [Web APIs]  |
  --------------------|-------------------|--------------| |---------------|
> setTimeout(() => {  | <global>          |              | | timeout, 1000 |
    console.log('hi') | setTimeout        |              | |               |
  }, 1000)            |                   |              | |               |
                      |                   |              | |               |

setTimeout์˜ ์‹คํ–‰์ด ์™„๋ฃŒ๋˜๋ฉด..์š”์ฒญ๋œ 1000ms์˜ ์‹œ๊ฐ„ ๋™์•ˆ ๋Œ€๊ธฐํ•  Web API๋กœ ์ž‘์—…์„ ์˜คํ”„๋กœ๋“œ ํ•ฉ๋‹ˆ๋‹ค.

        [code]        |   [call stack]    | [Event Loop] | |   [Web APIs]  |
  --------------------|-------------------|--------------| |---------------|
  setTimeout(() => {  | <global>          |              | | timeout, 1000 |
    console.log('hi') |                   |              | |               |
  }, 1000)            |                   |              | |               |
                      |                   |              | |               |

Call Stack์— ๋” ์ด์ƒ ์‹คํ–‰ํ•  ๊ฒƒ์ด ์—†๋‹ค๋Š” ๊ฒƒ์€ js๋„ ์‹คํ–‰ํ•  ๊ฒƒ์ด ์—†๋‹ค๋Š” ๋œป ์ž…๋‹ˆ๋‹ค.

        [code]        |   [call stack]    | [Event Loop] | |   [Web APIs]  |
  --------------------|-------------------|--------------| |---------------|
  setTimeout(() => {  |                   |              | | timeout, 1000 |
    console.log('hi') |                   |              | |               |
  }, 1000)            |                   |              | |               |
                      |                   |              | |               |

๊ทธ๋ฆฌ๊ณ  ๋‚˜์„œ์•ผ, Web APIs๊ฐ€ ๊ฐ€๋™ํ•˜๊ฒŒ ๋˜๊ณ , 1000ms๊ฐ€ ๋๋‚˜๊ฒŒ ๋˜๋ฉด ์ด๋ฒคํŠธ ๋ฃจํ”„์— ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ JS์— ์•Œ๋ฆฝ๋‹ˆ๋‹ค. 

์ด๋ฏธ ์‹คํ–‰ ์ค‘์ธ ์ฝ”๋“œ๋ฅผ ๋ฐฉํ•ดํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— Call Stack์— ์ง์ ‘ ํ‘ธ์‹œํ•˜์ง€ ์•Š์œผ๋ฉฐ ์ด์ƒํ•œ ์ƒํ™ฉ์— ๋น ์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ฐธ๊ณ ๋กœ ์ด๋ฒคํŠธ ๋ฃจํ”„๋Š” ํ๋กœ์จ ๊ฐ€์žฅ ๋จผ์ € push๋œ ํ•ญ๋ชฉ์ด ๊ฐ€์žฅ ๋จผ์ € Pop ๋˜์–ด ์‚ฌ๋ผ์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. (์„ ์ž…์„ ์ถœ)

        [code]        |   [call stack]    | [Event Loop] | |   [Web APIs]  |
  --------------------|-------------------|--------------| |---------------|
  setTimeout(() => {  | function        <---function     | |               |
    console.log('hi') |                   |              | |               |
  }, 1000)            |                   |              | |               |
                      |                   |              | |               |
        [code]        |   [call stack]    | [Event Loop] | |   [Web APIs]  |
  --------------------|-------------------|--------------| |---------------|
  setTimeout(() => {  | function          |              | |               |
    console.log('hi') |                   |              | |               |
  }, 1000)            |                   |              | |               |
                      |                   |              | |               |
> hi

๋งˆ์ง€๋ง‰์œผ๋กœ ์ด ํ•จ์ˆ˜์—๋Š” ์‹คํ–‰ํ•  ๋‹ค๋ฅธ ๋ช…๋ น์ด ์—†์œผ๋ฏ€๋กœ ํ˜ธ์ถœ ์Šคํƒ์—์„œ ์ œ๊ฑฐ๋ฉ๋‹ˆ๋‹ค.

๊ทธ๋ ‡๊ฒŒ ์šฐ๋ฆฌ์˜ ํ”„๋กœ๊ทธ๋žจ์€ ์‹คํ–‰์ด ์ข…๋ฃŒ๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

        [code]        |   [call stack]    | [Event Loop] | |   [Web APIs]  |
  --------------------|-------------------|--------------| |---------------|
  setTimeout(() => {  |                   |              | |               |
    console.log('hi') |                   |              | |               |
  }, 1000)            |                   |              | |               |
                      |                   |              | |               |
> hi

 

 

๋ฐ˜์‘ํ˜•

๊ด€๋ จ๊ธ€ ๋”๋ณด๊ธฐ

๋Œ“๊ธ€ ์˜์—ญ