Skip to content

Commit

Permalink
Merge pull request #1271 from nincoding/nincoding
Browse files Browse the repository at this point in the history
42μž₯ 비동기 ν”„λ‘œκ·Έλž˜λ° - ν•œμˆ˜μ§€
  • Loading branch information
Ryan-Dia authored Jan 25, 2024
2 parents 80a840a + 378a653 commit 2ed3156
Showing 1 changed file with 142 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
## 42μž₯. ✨ 비동기 ν”„λ‘œκ·Έλž˜λ°

### πŸ“Œ 42-1. 동기 μ²˜λ¦¬μ™€ 비동기 처리

> `ν•¨μˆ˜μ˜ μ‹€ν–‰ μˆœμ„œλŠ” μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ μŠ€νƒμœΌλ‘œ 관리`ν•˜λ©°, **μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진은 단 ν•˜λ‚˜μ˜ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ μŠ€νƒ**을 κ°–μŠ΅λ‹ˆλ‹€.
ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λ©΄, ν•¨μˆ˜ μ½”λ“œκ°€ ν‰κ°€λ˜μ–΄ ν•¨μˆ˜ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκ°€ μƒμ„±λ©λ‹ˆλ‹€.

μ΄λ•Œ μƒμ„±λœ ν•¨μˆ˜ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈλŠ” μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ μŠ€νƒ(= μ½œμŠ€νƒ)에 ν‘Έμ‰¬λ˜κ³  ν•¨μˆ˜μ½”λ“œκ°€ μ‹€ν–‰λ©λ‹ˆλ‹€.

ν•¨μˆ˜ μ½”λ“œμ˜ 싀행이 μ’…λ£Œν•˜λ©΄ ν•¨μˆ˜ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈλŠ” μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ μŠ€νƒμ—μ„œ νŒλ˜μ–΄ μ œκ±°λ©λ‹ˆλ‹€.

```js
const foo () => {};
const bar () => {};

foo();
bar();
```

![](https://velog.velcdn.com/images/ninto_2/post/b3129d02-5de0-4ecd-b37a-9fb2557fe7c2/image.png)

μœ„μ™€ 같이 μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ μŠ€νƒμ€ LIFO (Last In First Out) λ°©μ‹μœΌλ‘œ κ°€μž₯ 늦게 λ“€μ–΄μ˜¨ ν•¨μˆ˜ μ»¨ν…μŠ€νŠΈκ°€ κ°€μž₯ λ¨Όμ € λ‚˜κ°€λŠ” ꡬ쑰λ₯Ό 가지고 μžˆμŠ΅λ‹ˆλ‹€.

**μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ μŠ€νƒμ— ν•¨μˆ˜ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκ°€ ν‘Έμ‹œλ˜λŠ”κ²ƒμ€ ν•¨μˆ˜ μ‹€ν–‰μ˜ μ‹œμž‘**을 μ˜λ―Έν•©λ‹ˆλ‹€.

μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ μŠ€νƒμ˜ μ΅œμƒμœ„ μš”μ†ŒμΈ `μ‹€ν–‰ 쀑인 μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ`λ₯Ό `μ œμ™Έν•œ λͺ¨λ“  μ‹€ν–‰ μ»¨ν…μŠ€νŠΈλŠ” λͺ¨λ‘ μ‹€ν–‰ λŒ€κΈ° 쀑인 νƒœμŠ€ν¬` λ“€μž…λ‹ˆλ‹€.

> 이처럼, **μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진은 ν•œλ²ˆμ— ν•˜λ‚˜μ˜ νƒœμŠ€ν¬λ§Œ μ‹€ν–‰ν•  수 μžˆλŠ” μ‹±κΈ€ μŠ€λ ˆλ“œ 방식**으둜 λ™μž‘ν•©λ‹ˆλ‹€.
**μ‹±κΈ€ μŠ€λ ˆλ“œ 방식**에선, `ν•œ λ²ˆμ— ν•˜λ‚˜μ˜ νƒœμŠ€ν¬λ§Œ μ‹€ν–‰` ν•  수 있기 λ•Œλ¬Έμ— **μ²˜λ¦¬μ— μ‹œκ°„μ΄ κ±Έλ¦¬λŠ” νƒœμŠ€ν¬λ₯Ό μ‹€ν–‰ν•˜λŠ” 경우 λΈ”λ‘œν‚Ή(= μž‘μ—…μ€‘λ‹¨)이 λ°œμƒ**ν•˜κ²Œ λ©λ‹ˆλ‹€.

> `ν˜„μž¬ μ‹€ν–‰ 쀑인 νƒœμŠ€ν¬κ°€ μ’…λ£Œλ  λ•ŒκΉŒμ§€ λ‹€μŒμ— 싀행될 νƒœμŠ€ν¬κ°€ λŒ€κΈ°`ν•˜λŠ” 방식을 `동기(synchronous)처리` 라고 ν•©λ‹ˆλ‹€.
**동기 처리 방식은 νƒœμŠ€ν¬λ₯Ό μˆœμ„œλŒ€λ‘œ ν•˜λ‚˜μ”© 처리**ν•˜λ―€λ‘œ, **μ‹€ν–‰ μˆœμ„œκ°€ 보μž₯**은 λ˜μ§€λ§Œ **μ•žμ„  νƒœμŠ€ν¬κ°€ μ’…λ£Œν•  λ•ŒκΉŒμ§€ λ‹€λ₯Έ νƒœμŠ€ν¬λ“€μ€ λΈ”λ‘œν‚Ή**λœλ‹€λŠ” 단점을 가지고 μžˆμŠ΅λ‹ˆλ‹€.

```js
function foo() {
console.log("foo");
}

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

// setTimeout은 일정 μ‹œκ°„μ΄ κ²½κ³Όν•œ 이후, 콜백 ν•¨μˆ˜ fooλ₯Ό ν˜ΈμΆœν•©λ‹ˆλ‹€.
// setTimeout은 bar ν•¨μˆ˜λ₯Ό λΈ”λ‘œν‚Ήν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
setTimeout(foo, 3 * 1000);
bar();
```

μœ„ μ½”λ“œλ₯Ό μ‚΄νŽ΄λ³΄λ©΄, setTimeout ν•¨μˆ˜ μ΄ν›„μ˜ νƒœμŠ€ν¬λ₯Ό λΈ”λ‘œν‚Ήν•˜μ§€ μ•Šκ³  κ³§λ°”λ‘œ μ‹€ν–‰ν•©λ‹ˆλ‹€.

![](https://velog.velcdn.com/images/ninto_2/post/cd909334-a78e-4dcb-a188-d4c52ccc8691/image.png)

> 이처럼 `ν˜„μž¬ 싀행쀑인 νƒœμŠ€ν¬κ°€ μ’…λ£Œλ˜μ§€ μ•Šμ€ μƒνƒœλΌ 해도, λ‹€μŒ νƒœμŠ€ν¬λ₯Ό κ³§λ°”λ‘œ μ‹€ν–‰`ν•˜λŠ” 방식을 `비동기(asynchronous) 처리`라고 ν•©λ‹ˆλ‹€.
`비동기 처리 방식`은, **λ‹€μŒ νƒœμŠ€ν¬λ₯Ό κ³§λ°”λ‘œ μ‹€ν–‰ν•˜λ―€λ‘œ λΈ”λ‘œν‚Ήμ΄ λ°œμƒν•˜μ§€ μ•ŠλŠ”λ‹€**λŠ” μž₯점을 κ°€μ§€μ§€λ§Œ, **νƒœμŠ€ν¬μ˜ μ‹€ν–‰ μˆœμ„œκ°€ 보μž₯λ˜μ§€ μ•ŠλŠ”λ‹€**λŠ” 단점을 κ°€μ§‘λ‹ˆλ‹€.

비동기 처리λ₯Ό μˆ˜ν–‰ν•˜λŠ” `비동기 ν•¨μˆ˜`λŠ” μ „ν†΅μ μœΌλ‘œ `콜백 νŒ¨ν„΄μ„ μ‚¬μš©`ν•©λ‹ˆλ‹€.

![](https://velog.velcdn.com/images/ninto_2/post/22369bf8-354a-4b18-af3b-0915ea670401/image.png)

ν•˜μ§€λ§Œ, 이 **콜백 νŒ¨ν„΄μ€ 콜백 헬을 λ°œμƒμ‹œμΌœ 가독성을 λ‚˜μ˜κ²Œν•˜κ³ , 비동기 처리 쀑 λ°œμƒν•œ 예러의 μ˜ˆμ™Έ μ²˜λ¦¬κ°€ κ³€λž€ν•˜λ©°, μ—¬λŸ¬κ°œμ˜ 비동기 처리λ₯Ό ν•œ λ²ˆμ— μ²˜λ¦¬ν•˜λŠ”λ°λ„ ν•œκ³„**κ°€ μžˆμŠ΅λ‹ˆλ‹€.

이λ₯Ό λ³΄μ™„ν•˜κΈ° μœ„ν•΄, `Promise와 같은 비동기 ν•¨μˆ˜κ°€ λ“±μž₯`ν•˜μ˜€μŠ΅λ‹ˆλ‹€.

μΆ”κ°€μ μœΌλ‘œ, **타이머 ν•¨μˆ˜μΈ setTimeoutκ³Ό setInterval, HTTP μš”μ²­, 이벀트 ν•Έλ“€λŸ¬λŠ” 비동기 처리 방식**으둜 λ™μž‘ν•©λ‹ˆλ‹€.

<br>

---

### πŸ“Œ 42-2. 이벀트 루프와 νƒœμŠ€ν¬ 큐

μ•žμ„œ μ‚΄νŽ΄λ³Έ 것 처럼, **μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” μ‹±κΈ€ μŠ€λ ˆλ“œλ‘œ λ™μž‘**ν•©λ‹ˆλ‹€.

- μ‹±κΈ€ μŠ€λ ˆλ“œ : ν•œ λ²ˆμ— ν•˜λ‚˜μ˜ νƒœμŠ€ν¬λ§Œ 처리 κ°€λŠ₯

ν•˜μ§€λ§Œ λΈŒλΌμš°μ €κ°€ λ™μž‘ν•˜λŠ” 것을 μ‚΄νŽ΄λ³΄λ©΄ λ§Žμ€ νƒœμŠ€ν¬κ°€ λ™μ‹œμ— μ²˜λ¦¬λ˜λŠ” 것 처럼 λŠκ»΄μ§‘λ‹ˆλ‹€.

ex. HTML μš”μ†Œκ°€ μ• λ‹ˆλ©”μ΄μ…˜μ„ 톡해 μ›€μ§μ΄λ©΄μ„œ 이벀트 처리, HTTP μš”μ²­μ„ 톡해 μ„œλ²„λ‘œλΆ€ν„° 데이터λ₯Ό 가지고 μ˜€λ©΄μ„œ λ Œλ”λ§ λ“±...

> `이벀트 루프`λŠ” **μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ λ™μ‹œμ„±μ„ 지원**ν•©λ‹ˆλ‹€.
이벀트 λ£¨ν”„λŠ” λΈŒλΌμš°μ €μ— λ‚΄μž₯λ˜μ–΄ μžˆλŠ” κΈ°λŠ₯ 쀑 ν•˜λ‚˜μž…λ‹ˆλ‹€.

![](https://velog.velcdn.com/images/ninto_2/post/ab2951d5-def5-418d-880d-7dfceb6eace6/image.png)

κ΅¬κΈ€μ˜ V8 μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진을 λΉ„λ‘―ν•œ `λŒ€λΆ€λΆ„μ˜ μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진은 크게 μ½œμŠ€νƒκ³Ό νž™μ΄λΌλŠ” 2개의 μ˜μ—­μœΌλ‘œ ꡬ뢄`ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

#### πŸ”Ž 1. μ½œμŠ€νƒ (Call Stack) = μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ μŠ€νƒ

`μ†ŒμŠ€μ½”λ“œ(μ „μ—­ μ½”λ“œλ‚˜ ν•¨μˆ˜ μ½”λ“œ λ“±) 평가 κ³Όμ •μ—μ„œ μƒμ„±λœ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκ°€ μΆ”κ°€λ˜κ³ , μ œκ±°λ˜λŠ” μŠ€νƒ 자료ꡬ쑰`인 μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ μŠ€νƒμž…λ‹ˆλ‹€.

ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λ©΄ ν•¨μˆ˜ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκ°€ **순차적으둜 콜 μŠ€νƒμ— ν‘Έμ‹œλ˜μ–΄ 순차적으둜 μ‹€ν–‰**λ©λ‹ˆλ‹€.

μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진은 ν•˜λ‚˜μ˜ 콜 μŠ€νƒμ„ μ‚¬μš©ν•˜κΈ° λ•Œλ¬Έμ—, μ΅œμƒμœ„ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκ°€ μ’…λ£Œλ˜μ–΄ 콜 μŠ€νƒμ—μ„œ 제거되기 μ „κΉŒμ§€λŠ” λ‹€λ₯Έ μ–΄λ–€ νƒœμŠ€ν¬λ„ μ‹€ν–‰λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. (λΈ”λ‘œν‚Ή)

#### πŸ”Ž 2. νž™ (Heap)

νž™μ€ `객체가 μ €μž₯λ˜λŠ” λ©”λͺ¨λ¦¬ 곡간`μž…λ‹ˆλ‹€.

콜 μŠ€νƒμ˜ μš”μ†ŒμΈ **μ‹€ν–‰ μ»¨ν…μŠ€νŠΈλŠ” νž™μ— μ €μž₯된 객체λ₯Ό μ°Έμ‘°**ν•©λ‹ˆλ‹€.

λ©”λͺ¨λ¦¬μ— 값을 μ €μž₯ν•˜λ €λ©΄ λ¨Όμ € 값을 μ €μž₯ν•  λ©”λͺ¨λ¦¬ κ³΅κ°„μ˜ 크기λ₯Ό κ²°μ •ν•΄μ•Ό ν•©λ‹ˆλ‹€.

κ°μ²΄λŠ” μ›μ‹œ κ°’κ³ΌλŠ” 달리 크기가 μ •ν•΄μ Έ μžˆμ§€ μ•ŠκΈ° λ•Œλ¬Έμ—, ν• λ‹Ήν•΄μ•Ό ν•  `λ©”λͺ¨λ¦¬ κ³΅κ°„μ˜ 크기λ₯Ό λŸ°νƒ€μž„μ— κ²°μ •`ν•΄μ•Ό ν•©λ‹ˆλ‹€. (= `동적 ν• λ‹Ή`)

λ”°λΌμ„œ, 객체가 μ €μž₯λ˜λŠ” λ©”λͺ¨λ¦¬ 곡간인 **νž™μ€ ꡬ쑰화 λ˜μ–΄μžˆμ§€ μ•Šλ‹€**λŠ” νŠΉμ§•μ΄ μžˆμŠ΅λ‹ˆλ‹€.

`콜 μŠ€νƒκ³Ό νž™μœΌλ‘œ κ΅¬μ„±λ˜μ–΄ μžˆλŠ” μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진`은 `λ‹¨μˆœνžˆ νƒœμŠ€ν¬κ°€ μš”μ²­λ˜λ©΄ 콜 μŠ€νƒμ„ 톡해 μš”μ²­λœ μž‘μ—…μ„ 순차적으둜 μ‹€ν–‰`ν•  λΏμž…λ‹ˆλ‹€.

비동기 μ²˜λ¦¬μ—μ„œ μ†ŒμŠ€μ½”λ“œμ˜ 평가와 싀행을 μ œμ™Έν•œ λͺ¨λ“  μ²˜λ¦¬λŠ” μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진을 κ΅¬λ™ν•˜λŠ” ν™˜κ²½μΈ λΈŒλΌμš°μ € λ˜λŠ” Node.jsκ°€ λ‹΄λ‹Ήν•©λ‹ˆλ‹€.

> 이λ₯Ό μœ„ν•΄, `λΈŒλΌμš°μ € ν™˜κ²½μ€ νƒœμŠ€ν¬ 큐와 이벀트 루프λ₯Ό 제곡`ν•©λ‹ˆλ‹€.
#### πŸ”Ž 3. νƒœμŠ€ν¬ 큐 (task queue)

`setTimeout`μ΄λ‚˜ `setInterval`κ³Ό 같은 **비동기 ν•¨μˆ˜μ˜ 콜백 ν•¨μˆ˜ λ˜λŠ” 이벀트 ν•Έλ“€λŸ¬κ°€ μΌμ‹œμ μœΌλ‘œ λ³΄κ΄€λ˜λŠ” μ˜μ—­**μž…λ‹ˆλ‹€.

참고둜, ν”„λ‘œλ―ΈμŠ€μ˜ 후속 처리 λ©”μ„œλ“œμ˜ 콜백 ν•¨μˆ˜κ°€ μΌμ‹œμ μœΌλ‘œ λ³΄κ΄€λ˜λŠ” λ§ˆμ΄ν¬λ‘œνƒœμŠ€ν¬ 큐도 μ‘΄μž¬ν•©λ‹ˆλ‹€.

#### πŸ”Ž 4. 이벀트 루프 (event loop)

`콜 μŠ€νƒμ— ν˜„μž¬ μ‹€ν–‰ 쀑인 μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκ°€ μžˆλŠ”μ§€`, 그리고 `νƒœμŠ€ν¬ 큐에 λŒ€κΈ° 쀑인 ν•¨μˆ˜(콜백 ν•¨μˆ˜, 이벀트 ν•Έλ“€λŸ¬ λ“±)κ°€ μžˆλŠ”μ§€` `λ°˜λ³΅ν•΄μ„œ 확인`ν•©λ‹ˆλ‹€.

λ§Œμ•½ **콜 μŠ€νƒμ΄ λΉ„μ–΄μžˆκ³ , νƒœμŠ€ν¬ 큐에 λŒ€κΈ° 쀑인 ν•¨μˆ˜κ°€ μžˆλŠ” 상황**이라면 **이벀트 λ£¨ν”„λŠ” 순차적(FIFO, first in First Out, 큐)으둜 νƒœμŠ€ν¬ 큐에 λŒ€κΈ° 쀑인 ν•¨μˆ˜λ₯Ό 콜 μŠ€νƒμœΌλ‘œ 이동**μ‹œν‚΅λ‹ˆλ‹€.

μ΄λ•Œ 콜 μŠ€νƒμœΌλ‘œ μ΄λ™ν•œ ν•¨μˆ˜λŠ” 싀행이 λ©λ‹ˆλ‹€.

즉, `νƒœμŠ€ν¬ 큐에 μΌμ‹œ λ³΄κ΄€λœ ν•¨μˆ˜λ“€μ€ 비동기 처리 λ°©μ‹μœΌλ‘œ λ™μž‘`ν•©λ‹ˆλ‹€.

> `μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진은 μ‹±κΈ€ μŠ€λ ˆλ“œ 방식`으둜 λ™μž‘ν•˜μ§€λ§Œ, `λΈŒλΌμš°μ € ν™˜κ²½μ€ λ©€ν‹° μŠ€λ ˆλ“œ`둜 λ™μž‘ν•©λ‹ˆλ‹€.
λ§Œμ•½ λͺ¨λ“  μžλ°”μŠ€ν¬λ¦½νŠΈ μ½”λ“œκ°€ μžλ°”μŠ€ν¬λ¦½νŠΈ μ—”μ§„μ—μ„œ μ‹±κΈ€ μŠ€λ ˆλ“œ λ°©μ‹μœΌλ‘œ λ™μž‘ν•œλ‹€λ©΄ μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” 비동기 λ™μž‘ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

이처럼, **λΈŒλΌμš°μ € ν™˜κ²½μ΄ λ©€ν‹° μŠ€λ ˆλ“œ λ°©μ‹μœΌλ‘œ 이벀트 루프와 νƒœμŠ€ν¬ 큐λ₯Ό 톡해 비동기 λ™μž‘μ„ 지원**ν•˜κΈ° λ•Œλ¬Έμ— **μžλ°”μŠ€ν¬λ¦½νŠΈ μ½”λ“œμ—μ„œ 비동기 ν”„λ‘œκ·Έλž˜λ°μ΄ κ°€λŠ₯**ν•΄μ‘ŒμŠ΅λ‹ˆλ‹€.

μ΄λŸ¬ν•œ ꡬ쑰 덕뢄에 λΈŒλΌμš°μ €λŠ” μ—¬λŸ¬ μž‘μ—…μ„ λ™μ‹œμ— μ²˜λ¦¬ν•˜κ³ , μ›Ή νŽ˜μ΄μ§€κ°€ 응닡성을 μœ μ§€ν•˜λ©΄μ„œλ„ 비동기 ν”„λ‘œκ·Έλž˜λ°μ΄ κ°€λŠ₯ν•΄μ‘ŒμŠ΅λ‹ˆλ‹€.

μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œλŠ” `비동기 ν”„λ‘œκ·Έλž˜λ°`을 μœ„ν•΄ 주둜 `콜백 ν•¨μˆ˜, Promise, async/await λ“±μ˜ νŒ¨ν„΄μ„ μ‚¬μš©`ν•©λ‹ˆλ‹€.

0 comments on commit 2ed3156

Please sign in to comment.