JS asynchronous
Table of contents
μλ°μ€ν¬λ¦½νΈμ λΉλκΈ°(asynchronous)
μλ°μ€ν¬λ¦½νΈλ Single-Thread κΈ°λ°
μλ°μ€ν¬λ¦½νΈ μμ§μ΄ λμνλ λΈλΌμ°μ νκ²½μ΄λ Node.js νκ²½μ νλ²μ νλμ νμ€ν¬(task)λ§μ μ€νν μ μλ μ±κΈ μ€λ λ(single thread) μ΄λ€.
νλ²μ νλμ νμ€ν¬λ§ μ²λ¦¬
μλ°μ€ν¬λ¦½νΈλ ν¨μμ μ€ν μμλ₯Ό μ€ν 컨ν μ€νΈ μ€νμΌλ‘ κ΄λ¦¬νκ³ μλ°μ€ν¬λ¦½νΈ μμ§μ λ¨ νλμ μ€ν 컨ν μ€νΈ μ€ν μ κ°λλ€. λλ¬Έμ νλ²μ νλμ νμ€ν¬λ§μ μ²λ¦¬ν μ μκ³ , μ΄κ²μ μ½ μ€ν μ΄λΌ λΆλ₯Έλ€.
one thread == one call stack == one thing at a time
νλμ νμ€ν¬λ§μ μ€νν μ μκΈ° λλ¬Έμ μκ°μ΄ μ€λ 걸리λ νμ€ν¬λ₯Ό μ€ννλ©΄ λΈλ‘νΉμ΄ λ°μνλ€.
λΈλ‘νΉμ΄ λ°μνλ©΄ λΈλΌμ°μ νλ©΄μ΄ λ©μΆκ±°λ λλ €μ§λκ±Έ λ³Ό μ μλ€. μ΄λ νμ€ν¬λ₯Ό μ€ννλ λμ λλλ§μ΄ λΆκ°λ₯ νκΈ° λλ¬Έμ΄λ€.
μ½ μ€ν(Call stack, μ€ν 컨ν μ€νΈ μ€ν)
μμ€ μ½λ(μ μ μ½λλ ν¨μ μ½λ λ±) νκ°μ μν΄ μμ±λ μ€ν 컨ν μ€νΈκ° μΆκ°(push)λκ³ μ κ±°(pop)λλ μ€ν μλ£ κ΅¬μ‘°
λΈλ‘νΉ(Blocking, μμ μ€λ¨)
μ½λ μ€νμ λ리거λ λ©μΆκ² λ§λλ κ².
μλ°μ€ν¬λ¦½νΈλ λμμ±μ μ§μνλ€.
μλ°μ€ν¬λ¦½νΈλ μ±κΈ μ€λ λλ‘ λμνμ¬ νλ²μ νλμ νμ€ν¬λ§ μ²λ¦¬ν μ μλ λκΈ°μ μ²λ¦¬ λͺ¨λΈ μ΄μ§λ§ μ΄λ²€νΈ 루ν(Event Loop) μ νμ€ν¬ ν(Task Queues) λ₯Ό μ΄μ©ν΄ λμμ±(Concurrency) μ μ§μνμ¬ μ±κΈ μ€λ λμ λ¨μ μ 보μν΄ μ€λ€.
λκΈ°μ μ²λ¦¬ λͺ¨λΈ(Synchronous processing model)
μ€νμ€μΈ νμ€ν¬κ° μ’ λ£λ λκ°μ§ λ€μ μ€νλ νμ€ν¬κ° λκΈ°νλ λ°©μ
λΉλκΈ°μ μ²λ¦¬ λͺ¨λΈ(Asynchronous processing model)
νμ¬ μ€νμ€μΈ νμ€ν¬κ° μ’ λ£λμ§ μμ μνλΌ νλλΌλ λ€μ νμ€ν¬λ₯Ό 곧λ°λ‘ μ€ννλ λ°©μ
λΉλκΈ° νλ‘κ·Έλλ°
μλ°μ€ν¬λ¦½νΈλ μ±κΈ μ€λ λμ λ¨μ μ 극볡νκΈ° μν΄ λΉλκΈ° νλ‘κ·Έλλ°μ μ¬μ©νκ³ λΉλκΈ° μμ² μ²λ¦¬λ μλ°μ€ν¬λ¦½νΈ μμ§μ ꡬλνλ νκ²½μ΄ λ΄λΉ νλ€.
μ€μ μλ°μ€ν¬λ¦½νΈκ° ꡬλλλ νκ²½(λΈλΌμ°μ , Node.jsλ±)μμλ μ£Όλ‘ μ¬λ¬ κ°μ μ€λ λκ° μ¬μ©λλ©°, μ΄λ¬ν ꡬλ νκ²½μ΄ λ¨μΌ νΈμΆ μ€νμ μ¬μ©νλ μλ°μ€ν¬λ¦½νΈ μμ§κ³Ό μνΈ μ°λνκΈ° μν΄ μ¬μ©νλ μ₯μΉκ° λ°λ‘ 'μ΄λ²€νΈ 루ν' μΈ κ²μ΄λ€.
μκ°μ΄ μ€λ 걸리λ νμ€ν¬λ λ€λ₯Έ μ€λ λ(WebAPI, Node API)μ μμνκ³ λ Ό λΈλ‘νΉμΌλ‘ νμ€ν¬λ₯Ό μ²λ¦¬νλ€. μμ λ°μ μ€λ λμμ νμ€ν¬κ° μλ£λλ©΄ μ½λ°± ν¨μλ₯Ό Task Queueμ μΆκ° νλ€.
λ Ό λΈλ‘νΉ(Non-Blocking)
λ€λ₯Έ μ€λ λμ μμν νμ€ν¬λ₯Ό κΈ°λ€λ¦¬μ§ μκ³ λ°λ‘ λ€μ νμ€ν¬λ₯Ό μ²λ¦¬νλ κ².
Event Loop
μ½ μ€νμ νμ¬ μ€νμ€μΈ μ€ν 컨ν μ€νΈκ° μλμ§ κ·Έλ¦¬κ³ νμ€ν¬ νμ λκΈ° μ€μΈ ν¨μ(μ½λ°± ν¨μ, μ΄λ²€νΈ νΈλ€λ¬ λ±)κ° μλμ§ λ°λ³΅νμ¬ νμΈνλ€.
μ½ μ€νμ΄ λΉμ΄μλ€λ©΄ νμ€ν¬ νμμ λκΈ° μ€μΈ ν¨μλ₯Ό μμ°¨μ (FIFO)μΌλ‘ μ½ μ€νμΌλ‘ μ΄λμν¨λ€.
(μ΄λ νμ€ν¬ νμ μλ ν¨μλ€μ΄ μ½ μ€νμ λ€μ΄κ° νμ μ λ§λ€μ΄ μ£Όλ κ²μ΄ μλ°μ€ν¬λ¦½νΈ λΉλκΈ° νλ‘κ·Έλλ°μμ μ€μν μ μΈ κ² κ°λ€)
Task Queue(Event queue/Callback queue)
νμ€ν¬ νλ λΉλκΈ° μ²λ¦¬ ν¨μμ μ½λ°± ν¨μ λλ μ΄λ²€νΈ νΈλ€λ¬κ° μΌμμ μΌλ‘ 보κ΄λλ μμμ΄λ€.
μ΄κ³³μ μμ 보κ΄λ ν¨μλ€μ λΉλκΈ° μ²λ¦¬ λͺ¨λΈλ‘ λμνλ€.
λκΈ° μ€μΈ ν¨μλ μ½ μ€νμ΄ λΉμ΄μ‘μ λ Event loopμ μν΄ FIFOλ‘ μ½ μ€νμΌλ‘ μ΄λλμ΄ μ€νλλ€.
μμ
λΈλΌμ°μ μμ μ΄λ²€νΈ 루νκ° μ΄λ»κ² λμνλμ§ κ·Έλ¦ΌμΌλ‘ μ 보μ¬μ£Όλ μμ
const foo = () => console.log("First");const bar = () => setTimeout(() => console.log("Second"), 500);const baz = () => console.log("Third");bar();foo();baz();
μΆμ²: β¨β»οΈ JavaScript Visualized: Event Loop
μ μλ λ€λ₯΄μ§λ§ http://latentflip.com/loupeμ λ€μ΄κ° μ½λλ₯Ό μμ±νλ©΄ event loopκ° λμνλ λͺ¨μ΅μ μκ°ν ν΄μ€λ€.
μμ½
- μλ°μ€ν¬λ¦½νΈλ μ±κΈ μ€λ λμ΄λ€.
- μλ°μ€ν¬λ¦½νΈ μμ§μ λ¨ νλμ μ€ν 컨ν μ€νΈ μ€νμ κ°λλ€.
μλ°μ€ν¬λ¦½νΈλ μ±κΈ μ€λ λμ΄κ³ νλμ μ€ν 컨ν μ€νΈ νκ²½μ κ°κ³ μμΌλ©°, μ€νμ€μΈ νμ€ν¬κ° μ’ λ£λ λκ°μ§ λ€μ μ€νλ νμ€ν¬κ° λκΈ°νλ λκΈ°μ μ²λ¦¬ λͺ¨λΈμ΄λ€.
- λΉλκΈ° μμ² μ²λ¦¬λ μλ°μ€ν¬λ¦½νΈ μμ§μ ꡬλνλ νκ²½μΈ λΈλΌμ°μ λ Node.jsκ° λ΄λΉνλ€.
- μ΄λ²€νΈ 루νμ νμ€ν¬ νλ₯Ό μ΄μ©ν΄ λμμ±μ μ§μνλ€.
λΉλκΈ° μμ² μ²λ¦¬λ μλ°μ€ν¬λ¦½νΈ μμ§μ ꡬλνλ νκ²½μ΄ λ΄λΉνλ©°, μ΄λ²€νΈ 루νλ₯Ό μ΄μ©ν΄ λ¨μΌ μ½ μ€νκ³Ό μνΈ μ°λλλ€.
- λͺ¨λ λΉλκΈ° APIλ€μ μμ μ΄ μλ£λλ©΄ μ½λ°± ν¨μλ₯Ό νμ€ν¬ νμ μΆκ°νλ€.
- μ΄λ²€νΈ 루νλ 'νμ¬ μ€νμ€μΈ νμ€ν¬κ° μμ λ'(μ£Όλ‘ μ½ μ€νμ΄ λΉμμ‘μ λ) νμ€ν¬ νμ 첫 λ²μ§Έ νμ€ν¬λ₯Ό κΊΌλ΄μ μ€ννλ€.
λΉλκΈ° μμ μ΄ μλ£λλ©΄ μ½λ°± ν¨μλ₯Ό νμ€ν¬ νμ μΆκ°νκ³ μ΄λ²€νΈ 루νλ μ½ μ€νμ΄ λΉμμ Έ μμ λ νμ€ν¬ νμμ 첫 λ²μ§Έ νμ€ν¬λ₯Ό μ½ μ€νμΌλ‘ μ΄λμν€κ³ μ½ μ€νμ μ΄κ²μ μ€ννλ€.
ν μ€ μμ½
'μ±κΈ μ€λ λ κΈ°λ° μ΄μ§λ§ λΉλκΈ° μ²λ¦¬κ° κ°λ₯νλ€'
reference
What the heck is the event loop anyway? (μ΄ μμλΆν° 보면 μ΄ν΄νκΈ°κ° λ μ½λ€)
μλ°μ€ν¬λ¦½νΈμ μ΄λ²€νΈ 루ν