λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
javascript/πŸ“– study

[μŠ€ν„°λ”” 10μ£Όμ°¨]42μž₯- 비동기 ν”„λ‘œκ·Έλž˜λ°

by HomieKim 2022. 4. 2.

비동기 ν”„λ‘œκ·Έλž˜λ°

동기 μ²˜λ¦¬μ™€ 비동기 처리

μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ κ°œλ… μ•Œκ³  κ°€κΈ°

  • ν•¨μˆ˜ 호좜 μ‹œ μ½”λ“œκ°€ 평가 λ˜μ–΄ μ½œμŠ€νƒμ— ν‘Έμ‹œ 되고 ν•¨μˆ˜ μ½”λ“œ 싀행이 μ’…λ£Œ 되면 ν•¨μˆ˜ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈλŠ” μŠ€νƒμ—μ„œ νŒλ˜μ–΄ 제거 됨
  • ν•¨μˆ˜ μ½”λ“œ 평가 과정을 톡해 ν•¨μˆ˜ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ 생성 됨
  • 즉, μ½œμŠ€νƒμ— ν•¨μˆ˜ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ ν‘Έμ‹œ 됨 === ν•¨μˆ˜ μ‹€ν–‰μ˜ μ‹œμž‘μ„ 의미
  • ν•¨μˆ˜μ˜ μ‹€ν–‰ μˆœμ„œλŠ” μ‹€ν–‰μ»¨ν…μŠ€νŠΈ μŠ€ν…μœΌλ‘œ 관리 됨

동기 처리 방식 이해

  • μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진은 단 ν•˜λ‚˜μ˜ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ μŠ€νƒ κ°–λŠ”λ‹€
  • λ™μ‹œμ— 2개 μ΄μƒμ˜ ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•  수 μ—†λ‹€λŠ” 것을 의미
  • μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ˜ μ΅œμƒμœ„ (μ‹€ν–‰ 쀑인 ν•¨μˆ˜)λ₯Ό μ œμ™Έν•˜κ³  λͺ¨λ‘ μ‹€ν–‰ λŒ€κΈ° 쀑인 νƒœμŠ€ν¬(Task)
  • μžλ°” 슀크립트 엔진은 ν•œ λ²ˆμ— ν•˜λ‚˜μ˜ νƒœμŠ€ν¬λ§Œ μ‹€ν–‰ν•  수 μžˆλŠ” μ‹±κΈ€ μŠ€λ ˆλ“œ(single thread) λ°©μ‹μœΌλ‘œ λ™μž‘
  • μ‹±κΈ€ μŠ€λ ˆλ“œ λ°©μ‹μ˜ 경우 μ²˜λ¦¬μ— μ‹œκ°„μ΄ κ±Έλ¦¬λŠ” νƒœμŠ€ν¬λ₯Ό μ‹€ν–‰ ν•˜λŠ” 경우 λΈ”λ‘œν‚Ή(blocking, μž‘μ—… 쀑단)

정리
ν˜„μž¬ μ‹€ν–‰ 쀑인 νƒœμŠ€ν¬κ°€ μ’…λ£Œν•  λ•ŒκΉŒμ§€ λ‹€μŒμ— μ‹€ν–‰ 될 νƒœμŠ€ν¬κ°€ λŒ€κΈ°ν•˜λŠ” 방식을 동기(synchronous) 처리 λΌκ³ ν•œλ‹€.
μ‹€ν–‰ μˆœμ„œ 보μž₯λ˜λŠ” μž₯점 μžˆμ§€λ§Œ λŒ€κΈ° 쀑인 νƒœμŠ€ν¬λ“€μ΄ λΈ”λ‘œν‚Ή λ˜λŠ” 단점이 μžˆλ‹€.

비동기 처리 방식 이해

  • setTimeout ν•¨μˆ˜ 경우 비동기 λ°©μ‹μœΌλ‘œ λ™μž‘
function foo() {
  console.log('foo');
}

function bar() {
  console.log('bar');
}

// 타이머 ν•¨μˆ˜ setTimeout은 일정 μ‹œκ°„μ΄ κ²½κ³Όν•œ 이후에 콜백 ν•¨μˆ˜ fooλ₯Ό ν˜ΈμΆœν•œλ‹€.
// 타이머 ν•¨μˆ˜ setTimeout은 bar ν•¨μˆ˜λ₯Ό λΈ”λ‘œν‚Ήν•˜μ§€ μ•ŠλŠ”λ‹€.
setTimeout(foo, 3 * 1000);
bar();
// bar 호좜 -> (3초 κ²½κ³Ό ν›„) foo 호좜
  • μ‹€ν–‰ 쀑인 νƒœμŠ€ν¬κ°€ μ’…λ£Œ λ˜μ§€ μ•Šμ€ μƒνƒœλΌ 해도 λ‹€μŒ νƒœμŠ€ν¬λ₯Ό κ³§λ°”λ‘œ μ‹€ν–‰ν•˜λŠ” 방식을 비동기(asynchronous) 처리 라고 ν•œλ‹€.
  • 동기 처리 방식과 λ°˜λŒ€λ‘œ λΈ”λ‘œν‚Ή λ˜μ§€ μ•ŠλŠ” μž₯점, μ‹€ν–‰ μˆœμ„œ 보μž₯ λ˜μ§€ μ•ŠλŠ” 단점 가짐
  • 타이머 ν•¨μˆ˜(setTimeout, setInterval), HTTP μš”μ²­, 이벀트 ν•Έλ“€λŸ¬λŠ” 비동기 처리 λ°©μ‹μœΌλ‘œ λ™μž‘

이벀트 루프와 νƒœμŠ€ν¬ 큐

벀트 λ£¨ν”„λŠ” λΈŒλΌμš°μ €μ— λ‚΄μž₯λ˜μ–΄ μžˆλŠ” κΈ°λŠ₯
μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” μ‹±κΈ€ μŠ€λ ˆλ“œ λ°©μ‹μœΌλ‘œ λ™μž‘ν•˜μ§€λ§Œ 이벀트 루프λ₯Ό 톡해 λ™μ‹œμ— νƒœμŠ€ν¬λ₯Ό μ²˜λ¦¬ν•˜λŠ” κ²ƒμ²˜λŸΌ λ™μž‘ κ°€λŠ₯

μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진은 크게 2개의 μ˜μ—­(μ½œμŠ€νƒ, νž™)으둜 ꡬ뢄

  • 콜 μŠ€νƒ(call stack)

    • μ†ŒμŠ€μ½”λ“œ 평가 κ³Όμ •μ—μ„œ μƒμ„±λœ μ‹€ν–‰ μ»¨νƒμŠ€νŠΈκ°€ μΆ”κ°€λ˜κ±° μ œκ±°λ˜λŠ” μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ μŠ€νƒμ„ 말함
    • μžλ°” 슀크립트 엔진은 단 ν•˜λ‚˜μ˜ μ½œμŠ€νƒμ„ μ‚¬μš©
    • μ΅œμƒμœ„ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκ°€ μ’…λ£Œλ˜μ–΄ 콜 μŠ€νƒμ—μ„œ 제거되기 μ „κΉŒμ§€λŠ” μ–΄λ–€ νƒœμŠ€ν¬λ„ μ‹€ν–‰λ˜μ§€ μ•ŠλŠ”λ‹€.
  • νž™(heap)

    • νž™μ€ 객체가 μ €μž₯λ˜λŠ” λ©”λͺ¨λ¦¬ 곡간
    • 콜 μŠ€νƒμ˜ μš”μ†ŒμΈ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈλŠ” νž™μ— μ €μž₯된 객체λ₯Ό μ°Έμ‘°
    • κ°μ²΄λŠ” μ›μ‹œκ°’κ³Ό 달리 크기가 μ •ν•΄μ Έ μžˆμ§€ μ•Šκ³  λŸ°νƒ€μž„μ— λ™μ μœΌλ‘œ κ²°μ •
    • 즉, νž™μ€ ꡬ쑰화 λ˜μ–΄ μžˆμ§€ μ•ŠμŒ
  • 즉, μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진은 콜 μŠ€νƒ 톡해 μš”μ²­λœ μž‘μ—…μ„ 순차적으둜 μ‹€ν–‰ ν•  뿐

  • 비동기 μ²˜λ¦¬μ—μ„œ 평가와 싀행을 μ œμ™Έν•œ λͺ¨λ“  μžλ¦¬λŠ” λΈŒλΌμš°μ € λ˜λŠ” nodeJSμ—μ„œ λ‹΄λ‹Ή

이λ₯Ό μœ„ν•΄ λΈŒλΌμš°μ € ν™˜κ²½μ€ νƒœμŠ€ν¬ 큐와 이벀트 루프λ₯Ό 제곡

  • νƒœμŠ€ν¬ 큐(task queue)

    • 비동기 콜백 ν•¨μˆ˜ λ˜λŠ” 이벀트 ν•Έλ“€λŸ¬κ°€ μΌμ‹œμ μœΌλ‘œ λ³΄κ΄€λ˜λŠ” μ˜μ—­
    • ν”„λ‘œλ―ΈμŠ€μ˜ 후속 처리 λ©”μ„œλ“œμ˜ 콜백 ν•¨μˆ˜κ°€ μΌμ‹œμ μœΌλ‘œ 보관 λ˜λŠ” 마이크둜 νƒœμŠ€ν¬ 큐도 쑴재
  • 이벀트 루프(event loop)

    • 이벀트 λ£¨ν”„λŠ” 콜 μŠ€νƒμ—μ„œ ν˜„μž¬ μ‹€ν–‰ 쀑인 μ»¨ν…μŠ€νŠΈκ°€ μžˆλŠ”μ§€, νƒœμŠ€ν¬ 큐에 λŒ€κΈ° 쀑인 ν•¨μˆ˜κ°€ μžˆλŠ”μ§€ λ°˜λ³΅ν•΄μ„œ 확인
    • 콜 μŠ€νƒμ΄ λΉ„μ–΄μžˆκ³  νƒœμŠ€ν¬ 큐에 λŒ€κΈ° 쀑인 ν•¨μˆ˜κ°€ μžˆλ‹€λ©΄ 이벀트 λ£¨ν”„λŠ” 순차적으둜 νƒœμŠ€ν¬ 큐에 λŒ€κΈ° 쀑인 ν•¨μˆ˜λ₯Ό 콜 μŠ€νƒμœΌλ‘œ 이동 μ‹œν‚¨λ‹€.

정리
μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” μ‹±κΈ€ μŠ€λ ˆλ“œ λ°©μ‹μœΌλ‘œ λ™μž‘
μ΄λ•Œ μ‹±κΈ€ μŠ€λ ˆλ“œλ‘œ λ™μž‘ν•˜λŠ” 것은 λΈŒλΌμš°μ €κ°€ μ•„λ‹ˆλΌ λΈŒλΌμš°μ €μ— λ‚΄μž₯된 μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진
μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진은 μ‹±κΈ€ μŠ€λ ˆλ“œλ‘œ λ™μž‘ ν•˜μ§€λ§Œ λΈŒλΌμš°μ €λŠ” λ©€ν‹° μŠ€λ ˆλ“œλ‘œ λ™μž‘

λŒ“κΈ€