π©π» μλ²½ν μ΄ν΄νλ λκΈ°/λΉλκΈ° & λΈλ‘νΉ/λ ΌλΈλ‘νΉ
λκΈ°/λΉλκΈ° & λΈλ‘νΉ/λ ΌλΈλ‘νΉ
νλ‘κ·Έλλ°μμ μΉ μλ² νΉμ μ μΆλ ₯(I/O)μ λ€λ£¨λ€ 보면 λκΈ°/λΉλκΈ° & λΈλ‘νΉ/λ ΌλΈλ‘νΉ μ΄λ¬ν μ©μ΄λ€μ μ ν΄λ³Έ κ²½νμ΄ νλ² μ―€μ μμ κ²μ΄λ€. λλΆλΆ μ¬λλ€μ μ©μ΄λ€μ΄ λνλ΄κ³ μ νλ νμμ λν΄μ λ©ν° νμ€νΉκ³Ό λ°μ ν κ΄λ ¨μ΄ μλ€λ κ²μ μκ³ μλ€. κ·Έλμ λ κ°λ μ λΉμ·ν κ²μΌλ‘ μ€ν΄νλ μ¬λλ€μ΄ κ½€ λ§λ€. π΅π«
λκΈ°/λΉλκΈ° μ λΈλ‘νΉ/λ ΌλΈλ‘νΉ μ΄ λ κ°λ μ νν ννλ λΉμ·ν΄ 보μΌμ§λΌλ, μλ‘ λ€λ₯Έ μ°¨μμμ μμ μ μν λ°©μμ μ€λͺ νλ κ°λ μ΄λ€. λκΈ°/λΉλκΈ°λ μμ²ν μμ μ λν΄ μλ£ μ¬λΆλ₯Ό μ κ²½ μ¨μ μμ μ μμ°¨μ μΌλ‘ μνν μ§ μλμ§μ λν κ΄μ μ΄κ³ ,λΈλ‘νΉ/λ ΌλΈλ‘νΉμ λ¨μ΄ κ·Έλλ‘ νμ¬ μμ μ΄ block(μ°¨λ¨, λκΈ°) λλλ μλλμ λ°λΌ λ€λ₯Έ μμ μ μνν μ μλμ§μ λν κ΄μ μ΄λ€.
μ΄μ²λΌ λ κ°λ
μ λν μλ―Έ μ°¨μ΄λ λͺ
ννμ§λ§, νλ‘κ·Έλλ°μμλ μ’
μ’
νΌμ©λμ΄ μ¬μ©λκΈ°λ νλ€. λνμ μΌλ‘ μλ°μ€ν¬λ¦½νΈμ setTimeout() ν¨μλ₯Ό μΌλ°μ μΌλ‘ λΉλκΈ° ν¨μλΌκ³ λ§ λΆλ₯΄μ§λ§ λμμ λ
ΌλΈλ‘νΉ ν¨μμ΄κΈ°λ νλ€. μ¦, μ°λ¦¬κ° νΈμμ λΆλ₯΄λ μλ°μ€ν¬λ¦½νΈ λΉλκΈ° ν¨μλ μ¬μ€ λΉλκΈ° + λ
ΌλΈλ‘νΉ ν¨μμΈ κ²μ΄λ€. λ°λΌμ μ΄λ€μ μ ννκ² κ΅¬λΆνκ³ μ΄ν΄νλ κ²μ΄ μ»΄ν¨ν° μν€ν
μ³λ₯Ό μ΄ν΄νλλ° μμ΄ μ€μνλ€.
λκΈ°(Synchronous) / λΉλκΈ°(Asynchronous)
λκΈ°(εζ)μ λΉλκΈ°(ιεζ)λ₯Ό μμ보기 μμ, μ΄ λ κ°λ μ νκΈμ΄ μλ μλ¨μ΄λ‘ νμ΅ νκΈΈ κ°λ ₯ν κΆμ₯νλ λ°λ€. μλνλ©΄ νκΈλ‘ μ§μνμλ©΄ 'κ°μ κΈ°κ°' λλ 'κ°μ μ£ΌκΈ°'λΌλ λ»μ νμλ₯Ό μ¬μ©νλλ° μ€νλ € μλ―Έλ₯Ό μ΄ν΄νλλ° μμ΄ λμ± νΌλλ§ μ£ΌκΈ° λλ¬Έμ΄λ€. κ·Έλμ μλ¨μ΄λ₯Ό ν보μλ©΄ Synchronousμ Synλ 그리μ€μ΄λ‘ 'ν¨κ»'μ΄λ λ»μ΄κ³ chronoλ 'μκ°'μ΄λΌλ λ»μ΄λ€.
μ¦, Synchronousλ μμ μκ°μ ν¨κ» λ§μΆ°μ μ€ννλ€ λΌλ λ»μΌλ‘ ν΄μλλ€. μμ μ λ§μΆ° μ€ννλ€λ λ§μ μμ²ν μμ μ λν΄ μλ£ μ¬λΆλ₯Ό λ°μ Έ μμ°¨λλ‘ μ²λ¦¬νλ κ²μ λ§νλ€. Asynchronousλ μμ AλΌλ μ λμ¬κ° λΆμ΄ λΆμ νλ ννμ΄λ€. κ·Έλμ λκΈ°μ λ°λλ‘ μμ²ν μμ μ λν΄ μλ£ μ¬λΆλ₯Ό λ°μ§μ§ μκΈ° λλ¬Έμ μμ μ λ€μ μμ μ κ·Έλλ‘ μννκ² λλ€.
λΉλκΈ°μ μ±λ₯ μ΄μ
λ³΄ν΅ λΉλκΈ° νΉμ§μ μ΄μ©νμ¬ μ±λ₯κ³Ό μ°κ΄μ§μ΄ λ§νλ€. μλνλ©΄ μμ²ν μμ μ λνμ¬ μλ£ μ¬λΆλ₯Ό μ κ²½μ°μ§ μκ³ μμ μ κ·Έλ€μ μμ μ μννλ€λ κ²μ, I/O μμ κ³Ό κ°μ λλ¦° μμ μ΄ λ°μν λ, κΈ°λ€λ¦¬μ§ μκ³ λ€λ₯Έ μμ μ μ²λ¦¬νλ©΄μ λμμ μ²λ¦¬νμ¬ λ©ν° μμ μ μ§νν μ μκΈ° λλ¬Έμ΄λ€. μ΄λ μ λ°μ μΈ μμ€ν μ±λ₯ ν₯μμ λμμ μ€ μ μλ€.
μλ₯Ό λ€μ΄, μΉ μ ν리μΌμ΄μ μμ λ°μ΄ν°λ² μ΄μ€ 쿼리λ₯Ό μννλ μμ μ΄ μλ€κ³ κ°μ ν΄λ³΄μ. μ΄ μμ μ λ§μΌ λκΈ°μ μΌλ‘ μννλ©΄, λ°μ΄ν°λ² μ΄μ€μμ μλ΅μ΄ μ¬ λκΉμ§ κΈ°λ€λ €μΌ νλ€. κ·Έλ¬λ©΄ μ΄ λ μΉ μ ν리μΌμ΄μ μ λ€λ₯Έ μμ²μ μ²λ¦¬νμ§ λͺ»νλ―λ‘, λκ·λͺ¨ νΈλν½μ΄ λ°μν κ²½μ° μΉ μ ν리μΌμ΄μ μ μ±λ₯μ΄ μ νλ μ μλ€. νμ§λ§ λΉλκΈ° λ°©μμΌλ‘ λ°μ΄ν°λ² μ΄μ€ 쿼리λ₯Ό μννλ©΄, λ°μ΄ν°λ² μ΄μ€μμ μλ΅μ΄ μ¬ λκΉμ§ κΈ°λ€λ¦¬λ λμμλ λ€λ₯Έ μμ²μ 'λμμ μ²λ¦¬'ν μ μκ² λλ€. μ΄λ κ² λΉλκΈ° λ°©μμ μ¬μ©νλ©΄, λκ·λͺ¨ νΈλν½μμλ μμ μ μΌλ‘ λμν μ μλ μΉ μ ν리μΌμ΄μ μ λ§λ€ μ μλ€.
μ¬κΈ°μ 'λμ μ²λ¦¬' λΌλ κ°λ μ λ κ° μ΄μμ μμ μ΄ λμμ μ€νλλ κ²μ μλ―Έ νλ€. μ΄λ λ©ν° μ€λ λλ λ©ν° νλ‘μΈμ±κ³Ό κ°μ λ°©μμΌλ‘ ꡬνλ μ μλ€. μλ°μ€ν¬λ¦½νΈ κ°μ κ²½μ° λΉλκΈ°λ‘ μμ μ μμ²νλ©΄ λΈλΌμ°μ μ λ΄μ₯λ λ©ν° μ€λ λλ‘ μ΄λ£¨μ΄μ§ Web APIμ μμ μ΄ μΈκ°λμ΄ λ©μΈ Call Stackκ³Ό μμ μ΄ λμμ μ²λ¦¬λκ² λλ€. μ½κ² λΉμ νμλ©΄ μμ μ λ°±κ·ΈλΌμ΄λμ μΈκ°νλ€κ³ μκ°νλ©΄ λλ€. λνμ μΈ λΉλκΈ° μμ μ μ’ λ₯λ‘λ μ λλ©μ΄μ μ€ν, λ€νΈμν¬ ν΅μ , λ§μ°μ€ ν€λ³΄λ μ λ ₯, νμ΄λ¨Έ λ± λ§λ€. λ€λ§ μλ°μ€ν¬λ¦½νΈ μ½λ μ€ν μ체λ Web APIκ° μλ Call Stackμμ μ€νλλ€.
λκΈ°μ λΉλκΈ°λ μμ μμ μ²λ¦¬ μ°¨μ΄
μμμ λκΈ°μ λΉλκΈ°λ₯Ό μμ²ν μμ μ λν΄ μλ£ μ¬λΆμ λν μ°¨μ΄λΌκ³ λ§νμλ€. μ΄λ₯Ό μ½κ² λ§νμλ©΄ μ¬λ¬κ°μ μμ² μμ μ μμ°¨μ μΌλ‘ μ²λ¦¬νλλ μλλμ λ°λ₯Έ μ°¨μ΄λ‘ 보면 λλ€. μμ²ν μμ μ λν μλ£ μλ¦Όμ λ°λμ λ°μμΌ λ€μ μμ μ μννλ€λ λ§μ μμ μ μμλλ‘ μ²λ¦¬νλ€λ λ§μ΄κΈ° λλ¬Έμ΄λ€. λ°λΌμ λκΈ° μμ μ μμ²ν μμ μ λν΄ μμκ° μ§μΌμ§λ κ²μ λ§νλ κ²μ΄κ³ , λΉλκΈ° μμ μ μμκ° μ§μΌμ§μ§ μμ μ μλ€λ κ²μ λ§νλ€.
μλ₯Όλ€μ΄ A, B, C λΌλ 3 κ°μ μμ (Task)μ΄ μλ€κ³ κ°μ νμ. λκΈ° λ°©μμΌλ‘ μ€ννλ©΄ A → B → C μμλλ‘ μ€νλκ² λκ³ , λΉλκΈ° λ°©μμΌλ‘ μ€ννλ©΄ A → C → B λλ C → A → B λ±μ 무μμμ μμλ‘ μ€νλκ² λλ κ²μ΄λ€.
μ 리νμλ©΄ μμ 3κ°λ₯Ό μμ²νλλ° μλ΅μμ κ·Έ μμκ° μ§μΌμ§λ€λ©΄ λκΈ°μ΄κ³ μ΄λ€ κ² λ¨Όμ μ¬μ§ λͺ¨λ₯Έλ€λ©΄ λΉλκΈ°λΌκ³ 보면 λλ€.
Blocking / Non-Blocking
λΈλ‘νΉκ³Ό λ ΌλΈλ‘νΉμ λ¨μ΄μμ μ μ μλ―μ΄ λ€λ₯Έ μμ²μ μμ μ μ²λ¦¬νκΈ° μν΄ νμ¬ μμ μ block(μ°¨λ¨, λκΈ°) νλ μνλμ μ 무λ₯Ό λνλ΄λ νλ‘μΈμ€μ μ€ν λ°©μμ΄λ€.
λκΈ°/λΉλκΈ°κ° μ 체μ μΈ μμ μ λν μμ°¨μ μΈ νλ¦ μ 무λΌλ©΄, λΈλ‘νΉ/λ ΌλΈλ‘νΉμ μ 체μ μΈ μμ μ νλ¦ μ체λ₯Ό λ§λ μ λ§λλ‘ λ³Ό μ μλ κ²μ΄λ€. μλ₯Ό λ€μ΄, νμΌμ μ½λ μμ μ΄ μμ λ, λΈλ‘νΉ λ°©μμΌλ‘ μ½μΌλ©΄ νμΌμ λ€ μ½μ λκΉμ§ λκΈ°νκ³ , λ ΌλΈλ‘νΉ λ°©μμΌλ‘ μ½μΌλ©΄ νμΌμ λ€ μ½μ§ μμλ λ€λ₯Έ μμ μ ν μ μλ€.
λΉλκΈ°μ λ ΌλΈλ‘νΉ κ°λ μ°¨μ΄
μλ§ μλ΄κΈ° κ°λ°μλ€μ΄ κ°μ₯ νΌλνλ λΆλΆμ΄ λΉλκΈ°μ λ
ΌλΈλ‘νΉμ μ°¨μ΄ λΆλΆμΌ κ²μ΄λ€. ν¬μ€ν
μ΄λ°μμ μλ°μ€ν¬λ¦½νΈμ setTimeout ν¨μλ₯Ό λΉλκΈ° ν¨μμ΄λ©° λμμ λ
ΌλΈλ‘νΉ ν¨μμ΄λΌκ³ νλ€. μ΄λ μ΄λ ν κ΄μ μΌλ‘ setTimeout μ λ°λΌλ³΄λλμ λ°λΌ κ°κΈ° λΆλ₯΄λκ² λ¬λΌμ§κΈ° λλ¬Έμ΄λ€. μλ₯Όλ€μ΄ μλ μ½λλ setTimeout ν¨μλ₯Ό μ¬μ©νμ¬ 1μ΄ νμ "Hello, world!"λ₯Ό μΆλ ₯νλ λΉλκΈ° λ
ΌλΈλ‘νΉ μ½λμ μμ μ΄λ€. μ½λλ₯Ό μ€ννλ©΄, "μμ"κ³Ό "λ"μ΄ λ¨Όμ μΆλ ₯λκ³ , 1μ΄ νμ "1μ΄ νμ μ€νλ©λλ€!"κ° μΆλ ₯λκ² λλ€.
console.log("μμ");
setTimeout(() => {
console.log("1μ΄ νμ μ€νλ©λλ€!");
}, 1000);
console.log("λ");
μ¦, μΆλ ₯ μμμ μ μλ μ½λ λΌμΈ μμκ° λ§μ§ μμ κ²μ΄λ€. μ΄λ setTimeout ν¨μμ λν΄ νμ΄λ¨Έ μμ
μλ£ μ¬λΆλ₯Ό μ κ²½ μ°μ§ μκ³ λ°λ‘ κ·Έ λ€μ μ½μ μμ
μ μννμκΈ° λλ¬Έμ΄λ€. κ·Έλ¦¬κ³ setTimeout ν¨μμ νμ΄λ¨Έ μμ
μλ£ μλμ μ½λ°± ν¨μλ₯Ό ν΅ν΄ κ°μ λ°μ μΆλ ₯νμλ€. λ°λΌμ setTimeout μ λΉλκΈ°(Asynchronouse)μ΄λ€.
λ€λ₯Έ μκ°μΌλ‘ 보면 λ©μΈ ν¨μ μμ
μ λν΄μ setTimeout ν¨μλ μμ μ νμ΄λ¨Έ μμ
μ μννκΈ° μν΄ λ©μΈ ν¨μλ₯Ό λΈλ½νμ§ μκ³ λ°±κ·ΈλΌμ΄λμμ λ³λλ‘ μ²λ¦¬λμλ€. λ©μΈ ν¨μλ₯Ό λΈλ½νμ§ μμΌλ setTimeout ν¨μλ₯Ό νΈμΆνκ³ λ°λ‘ κ·Έ λ€μ μ½μ ν¨μλ₯Ό νΈμΆν κ²μ΄λ€. λ°λΌμ setTimeout μ λ
ΌλΈλ‘νΉ(Non-blocking)μ΄λ€.
κ·Έλ°λ° κ²°κ΅μ λΉλκΈ°λ λ ΌλΈλ‘νΉμ΄λ μΆκ΅¬νλ κ²°κ³Όλ‘λ§ λ³΄μλ©΄ λμμ λ€λ₯Έ μμ μ μννλ€λ μ μμ κ·Έκ² κ·Έκ²μ΄λΌκ³ λ³Ό μλ μλ€. μ΄λ μμ κ³Ό κ΄λ ¨λ μ΄λ‘ μ μΈ κ°λ μ΄λΌ μ€μ μ½λμμ κ²½κ³λ₯Ό ꡬλΆνκΈ°κ° μ 맀νκΈ°λ νλ€. κ·Έλμ νλ‘κ·Έλλ°μμ μ΄λ₯Ό νΌμ©νμ¬ μ¬μ©νλ κ² κ°λ€. κ·Έλ¬λ μμ°ν λνλ΄λ μλ―Έλ λ€λ₯΄λ€. π΅
μ°λ¦¬κ° λκΈ°/λΉλκΈ°, λΈλ‘νΉ/λ ΌλΈλ‘νΉμ νΌλνλ μ΄μ λ, μλ°μ€ν¬λ¦½νΈλ₯Ό μ²μ λ°°μΈ λ νλ‘κ·Έλλ° μμ μ΄λ κ°μμμsetTimeoutκ³Ό κ°μ ν¨μλ₯Ό 'λΉλκΈ° ν¨μ' λΌκ³ μ§μΉνκ³ μΈμλ²λ €μ κ·Έλ λ€κ³ μκ°νλ€. κ·Έλμ 'λΉλκΈ°' λΌκ³ νλ©΄ μμ°μ€λ½κ² λ³λ ¬ μ€νμ λ μ¬λΌ λΉλκΈ°μ λ ΌλΈλ‘νΉμ νΌλνλ κ²μ΄λ€.
λΉλκΈ°λ μΆλ ₯ μμμ κ΄λ ¨λ κ°λ μ΄κ³ λ ΌλΈλ‘νΉμ΄ λ³λ ¬ μ€νκ³Ό κ΄λ ¨λ κ°λ μ΄λ€. λ°λΌμ κΈμ΄μ΄λ κ°μΈμ μΌλ‘ μ΄ λΆλΆμ μλͺ»λμλ€κ³ λΉννκ³ μΆλ€. μ무리 μ‘°κΈ λν΄ν κ°λ μ΄λΌλ μ²μλΆν° λΉλκΈ° + λ ΌλΈλ‘νΉ ν¨μλΌκ³ κ°λ₯΄μΉλκ²μ΄ μΆνλ₯Ό μν΄ κ°λ μ λ€μ‘λλ° μ³λ€κ³ λ³Έλ€.
λΉλκΈ° λ ΌλΈλ‘νΉκ³Ό μ½λ°± ν¨μ
μλ°μ€ν¬λ¦½νΈ λΉλκΈ° νλ‘κ·Έλλ°μμ λΉ μ§μ§ μλ κ°λ μ΄ λ°λ‘ μ½λ°±(callback) μ΄λ€. λΉλκΈ° λ ΌλΈλ‘νΉμ΄λ λ€λ₯Έ μμ μ κ²°κ³Όλ₯Ό κΈ°λ€λ¦¬μ§ μκ³ λ³λ ¬μ μΌλ‘ μ€νλλ λ°©μμ λ§νλλ°, μ΄λ λ€λ₯Έ μμ μ μλ£ μ¬λΆλ κ²°κ³Όμ λν νμ²λ¦¬λ₯Ό μν΄ μ΄μ©λλ λ°©μμ΄ μ½λ°± ν¨μμ΄λ€.
κ·ΈλΌ μ½λ°± ν¨μλ λΉλκΈ°μ κ΄λ ¨μ΄ μλ κ²μΌκΉ? λ ΌλΈλ‘νΉκ³Ό κ΄λ ¨μ΄ μλ κ²μΌκΉ? μ λ΅μ λλ€ κ΄λ ¨μ΄ μλ€. μλ°ν λ°μ§μλ©΄ μ½λ°± ν¨μλ λΉλκΈ° λ ΌλΈλ‘νΉμ ꡬννλ νλμ κΈ°μ μ΄μ§ κ°λ μ΄ μλλ€. μ½λ°± μ§μ₯(callback hell) λλ¬Έμ μ½λ°± ν¨μ λ°©μμΌλ‘ λΉλκΈ° λ ΌλΈλ‘νΉμ ꡬννκΈ° μ«λ€λ©΄ Promise κ°μ²΄λ₯Ό μ΄μ©νμ¬λ λκ³ μμ μ΄λ²€νΈλ‘ emit νμ¬ μ²λ¦¬νμ¬λ λλ€. λ°©λ²μ μ¬λ¬κ°μ§μ΄λ€. ν΅μ¬μ λΉλκΈ° λ ΌλΈλ‘νΉμ ꡬννλ κΈ°μ μ μ½λ°± μΈμ μ¬λ¬κ°μ§κ° μλ€λ μ μ΄κ³ μ½λ°±μ κ·Έ μ€ νλμΌ λΏμ΄λΌλ κ²μ΄μ§ λκΈ°/λΉλκΈ° & λΈλ‘νΉ/λ ΌλΈλ‘νΉ κ°λ κ³Ό μ§μ μ μΈ κ΄λ ¨μ μλ€.
/* μ½λ°± ν¨μ λ°©μμΌλ‘ ꡬνν λΉλκΈ° + λ
ΌλΈλ‘νΉ μλ² μμ² μμ
*/
$.ajax({
url: 'https://jsonplaceholder.typicode.com/todos/1',
type: 'GET',
dataType: 'json',
success: function(data) { // μμ²μ΄ μ±κ³΅νλ©΄ νΈμΆλ μ½λ°± ν¨μ
console.log(data);
},
error: function(err) { // μμ²μ΄ μ€ν¨νλ©΄ νΈμΆλ μ½λ°± ν¨μ
throw err;
}
});
// μμ²μ 보λ΄λ λμμ λ€λ₯Έ μμ
μ μνν μ μμ΅λλ€.
console.log('Hello');
/* νλ‘λ―Έμ€ κ°μ²΄ λ°©μμΌλ‘ ꡬνν λΉλκΈ° + λ
ΌλΈλ‘νΉ μλ² μμ² μμ
*/
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then((response) => {
return response.json();
})
.then((data) => {
console.log(data);
})
.catch((err) => {
throw err;
});
// μμ²μ 보λ΄λ λμμ λ€λ₯Έ μμ
μ μνν μ μμ΅λλ€.
console.log('Hello');
/* μ΄λ²€νΈ λ°©μμΌλ‘ ꡬνν λΉλκΈ° + λ
ΌλΈλ‘νΉ νμΌ λ€μ΄ μμ
*/
const fileReader = new FileReader(); // FileReader κ°μ²΄λ₯Ό μμ±
const input = document.querySelector('input');
const file = input.files[0]; // input νκ·Έμμ μ νλ νμΌμ κ°μ Έμ΅λλ€
fileReader.addEventListener('load', function() {
console.log(fileReader.result); // νμΌμ΄ loadκ° μλ£λλ©΄ λ΄μ©μ μΆλ ₯ν©λλ€.
});
fileReader.addEventListener('error', function(err) {
throw err;
});
// μμ²μ 보λ΄λ λμμ λ€λ₯Έ μμ
μ μνν μ μμ΅λλ€.
console.log('Hello');
λκ° μ μ΄κΆμ κ°μ§κ³ μλλ
λ€λ₯Έ μμ μμ λκΈ°/λΉλκΈ°μ λΈλ‘νΉ/λ ΌλΈλ‘νΉμ λ³΄λ€ λͺ νν ꡬλΆνκΈ° μν΄μ 'μ μ΄κΆ' μ΄λΌλ μ΄λ €μ΄ λ¨μ΄λ₯Ό μ΄λ€. μ μ΄κΆμ κ°λ¨ν λ§ν΄μ ν¨μμ μ½λλ νλ‘μΈμ€μ μ€ν νλ¦μ μ μ΄ν μ μλ κΆλ¦¬ κ°μ κ²μ΄λ€. μ΄ κ°λ μ μ΄μ체μ (OS)μ 컀λ(kernel)μμ λ°μ¨ κ°λ μΌλ‘ I/O λμμμ μ€λͺ νλ λΆλΆμ΄λ€. μ¦, Blockingκ³Ό Non-Blockingμ νΈμΆλ ν¨μ(callee)κ° νΈμΆν ν¨μ(caller)μκ² μ μ΄κΆμ λ°λ‘ μ£Όλλ μμ£Όλλλ‘ κ΅¬λΆλλ€. μ μ΄κΆμ΄ λμ΄κ°λ²λ¦¬λ©΄ ν΄λΉ μ€λ λλ λΈλ‘νΉλκ² λλ€.
λ€μμ A ν¨μμ B ν¨μ μμ μ λν΄ A ν¨μκ° B ν¨μλ₯Ό Blocking λ°©μμΌλ‘ νΈμΆν μ μ μ΄κΆ μνλ₯Ό λνλΈ κ·Έλ¦Όμ΄λ€.
- A ν¨μκ° B ν¨μλ₯Ό νΈμΆνλ©΄ Bμκ² μ μ΄κΆμ΄ λμ΄κ°λ€
- μ μ΄κΆμ λ겨λ°μ Bλ ν¨μλ₯Ό μ€ννλ€.
- μ΄λ Aλ Bμκ² μ μ΄κΆμ λ겨주μκΈ° λλ¬Έμ A ν¨μ μ€νμ μ μ λ©μΆλ€. (Block)
- B ν¨μκ° μ€νμ΄ λλλ©΄ μμ μ νΈμΆν Aμκ² μ μ΄κΆμ λλ €μ€λ€.
- μ μ΄κΆμ λ€μ λ°μ A ν¨μλ κ·Έλ€μ μμ μ μ€ννλ€.
λ€μμ A ν¨μμ B ν¨μ μμ μ λν΄ A ν¨μκ° B ν¨μλ₯Ό Non-Blocking λ°©μμΌλ‘ νΈμΆν μ μ μ΄κΆ μνλ₯Ό λνλΈ κ·Έλ¦Όμ΄λ€.
- A ν¨μκ° B ν¨μλ₯Ό νΈμΆνλ€.
- νΈμΆλ B ν¨μλ μ€νλμ§λ§, μ μ΄κΆμ A ν¨μκ° κ·Έλλ‘ κ°μ§κ³ μλλ€.
- A ν¨μλ κ³μ μ μ΄κΆμ κ°μ§κ³ μκΈ° λλ¬Έμ B ν¨μλ₯Ό νΈμΆν μ΄νμλ μμ μ μ½λλ₯Ό κ³μ μ€ννλ€.
λκΈ°/λΉλκΈ° + λΈλ‘νΉ/λ ΌλΈλ‘νΉ μ‘°ν©
μ§κΈκΉμ§ λκΈ°/λΉλκΈ° μ λΈλ‘νΉ/λ ΌλΈλ‘νΉ κ°κ°μ μ°¨μ΄μ μ λν΄ μμ보μλ€. μ΄μ²λΌ λμ μ μ¬νμ§λ§ μμ°ν λ€λ₯Έ κ°λ μ΄λ€. κ·Έλμ νλ‘κ·Έλ¨ μν€ν μ³μμλ μ΄ λ κ°λ μ΄ ν¨κ» μ‘°ν©λμ΄ μ¬μ©λλ€. μλ₯Όλ€μ΄ λ€μ 4κ°μ§λ‘ μ‘°ν©μ΄ κ°λ₯νλ€.
- Sync Blocking (λκΈ° + λΈλ‘νΉ)
- Async Blocking (λΉλκΈ° + λΈλ‘νΉ)
- Sync Non-Blocking (λκΈ° + λ ΌλΈλ‘νΉ)
- Async Non-Blocking (λΉλκΈ° + λ ΌλΈλ‘νΉ)
μ΄λ¬ν λκΈ°/λΉλκΈ°μ λΈλ‘νΉ/λ ΌλΈλ‘νΉμ μ‘°ν©μ νλ‘κ·Έλ¨μ΄ μλνλ λ°©μμ μν₯μ λ―ΈμΉλ μ€μν μμλ€. μ΄λ ν μμλ₯Ό μ‘°ν©νμ¬ μ¬μ©νλλμ λ°λΌ νλ‘κ·Έλ¨μ μ±λ₯κ³Ό ν¨μ¨μ±μ λμΌ μ μκΈ° λλ¬Έμ΄λ€.
λνμ μΈ μλ‘ Node.js λ₯Ό λ€ μ μλ€. Node.jsμμ λΉλκΈ° λ°©μμΌλ‘ νμΌμ μ½κ±°λ λ€νΈμν¬ μμ²μ λ³΄λΌ λλ λΉλκΈ° & λ ΌλΈλ‘νΉ λ°©μμ μ¬μ©νμ¬ μμ μ΄ μλ£λ λκΉμ§ λ€λ₯Έ μμ μ μνν μ μλλ‘ νλ€. λ°λ©΄μ, Node.jsμμ μ½λ μ€ν μμ μ λ¦μΆ°μ£Όκ±°λ μμ°¨μ μΈ μμ‘΄μ±μ΄ μλ μμ μ μ²λ¦¬ν λλ λκΈ° & λΈλ‘νΉ λ°©μμ μ¬μ©νμ¬ μμ μ μμμ νμ΄λ°μ μ μ΄ν μ μλλ‘ νλ€.
μλ§ μ°λ¦¬λ μ΄λ―Έ κ°λ μ΄ μ μ©λ νλ μμν¬λ₯Ό μ΄μ©ν΄ νΈλ¦¬νκ² μ¬μ©ν΄ μμ΄μ μλΏμ§ μμ μ μλ€. νμ§λ§ μ΄λ¬ν μ΄λ‘ μ μΈ λΆλΆμ μ΄ν΄νκ³ μ μ©νλ€λ©΄ μ§μ μ€κ³ν λ λμ± ν¨μ¨μ μΈ μ΄ν리μΌμ΄μ μ κ°λ°μ λμμ΄ λ μ μμΌλ©°, κ°λ λ€μ λͺ νν μκ³ μμΌλ©΄ Node.jsμ λμ μ리μ μ₯μ μ λ μ μ΄ν΄νκ³ νμ©ν μ μμ κ²μ΄λ€. λ°λΌμ λκΈ°/λΉλκΈ°μ λΈλ‘νΉ/λ ΌλΈλ‘νΉμ κ°λ μ μ΄ν΄νκ³ μ μ ν μ‘°ν©μ μ ννλ κ²μ΄ μ€μνλ€.
Sync Blocking μ‘°ν©
Sync Blocking μ‘°ν©μ λ€λ₯Έ μμ μ΄ μ§νλλ λμ μμ μ μμ μ μ²λ¦¬νμ§ μκ³ (Blocking), λ€λ₯Έ μμ μ μλ£ μ¬λΆλ₯Ό λ°λ‘ λ°μ μμ°¨μ μΌλ‘ μ²λ¦¬νλ (Sync) λ°©μμ΄λ€. λ€λ₯Έ μμ μ κ²°κ³Όκ° μμ μ μμ μ μν₯μ μ£Όλ κ²½μ°μ νμ©ν μ μλ€.
μ€μν λμ μμ
μ΄λ κ°λ°νμμ μ¬μ1, μ¬μ2, μ¬μ3 μ νμ₯μ΄ μλ€κ³ νμ. κ°λ°νμ₯μ κ°λ°ν μμ μ νλ¦μ μ‘°μ¨νκ³ , μ¬μλ€μκ² μ 무λ₯Ό μ§μνλ€κ³ νλ€.
- νμ₯ : μ¬μ1μ¨ μ 무 A μ’ ν΄μ£ΌμΈμ
- μ¬μ1 : λ€ μκ² μ΅λλ€. (Aλ₯Ό μ²λ¦¬μ€)
- νμ₯ : (μ¬μ1μ΄ Aλ₯Ό λ€ν λκΉμ§ μ무μΌλ νμ§ μκ³ κΈ°λ€λ¦°λ€)
- μ¬μ1 : νμ₯λ A μ 무 μλ£νμ΅λλ€.
- νμ₯ : μκ³ νμ΄μ. μ¬μ2μ¨ μ 무 Bμ’ ν΄μ£ΌμΈμ.
- μ¬μ2 : λ€ μκ² μ΅λλ€. (Bλ₯Ό μ²λ¦¬μ€)
- νμ₯ : (μ¬μ2κ° Bλ₯Ό λ€ν λκΉμ§ μ무μΌλ νμ§ μκ³ κΈ°λ€λ¦°λ€)
- μ¬μ2 : νμ₯λ B μ 무 μλ£νμ΅λλ€.
- νμ₯ : μκ³ νμ΄μ. μ¬μ3μ¨ μ 무 Cμ’ ν΄μ£ΌμΈμ.
- ...μλ΅
μ½λ λμ μμ
Sync Blocking μ λνμ μΈ μλ‘ νμΌμ μ½μ΄ λ΄μ©μ μ²λ¦¬νλ λ‘μ§μ λ€ μ μλ€. νμΌμ λ¨Όμ μ½μ΄μΌ κ·Έλ€μ μμ μ μ²λ¦¬ν μ μκΈ° λλ¬Έμ΄λ€.
const fs = require('fs'); // νμΌ μμ€ν
λͺ¨λ λΆλ¬μ€κΈ°
// λκΈ°μ μΌλ‘ νμΌ μ½κΈ°
const data1 = fs.readFileSync('file1.txt', 'utf8'); // file1μ syncμΌλ‘ read ν¨
console.log(data1); // νμΌ λ΄μ© μΆλ ₯νκ³ μ μ ν μ²λ¦¬λ₯Ό μ§ν
const data2 = fs.readFileSync('file2.txt', 'utf8');
console.log(data2);
const data3 = fs.readFileSync('file3.txt', 'utf8');
console.log(data3);
μ΄λ¬ν Sync Blocking μ μ½λκ° μμ°¨μ μΌλ‘ μ€νλλ νΉμ±μ κ°μ§κ³ μλ€. κ·Έλμ Sync Blocking μ‘°ν©μ μΌλ°μ μΌλ‘ μμ
μ΄ κ°λ¨νκ±°λ μμ
λμ΄ μ μ κ²½μ°μ μ¬μ©λλ€. μμ λ°μ΄ν°λ₯Ό μ²λ¦¬νκ±°λ νμΌ νλλ₯Ό μ½κ³ μ°λ κ²½μ°μλ Sync Blocking λ°©μμ΄ λ κ°λ¨νκ³ μ§κ΄μ μΌ μ μλ€. νμ§λ§ μμ
λμ΄ λ§κ±°λ μκ°μ΄ μ€λ 걸리λ μμ
μ μ²λ¦¬ν΄μΌ νλ κ²½μ°μλ Sync Blocking λ°©μμ μ¬μ©νλ©΄ λ
μ΄ λλ€. μλνλ©΄ μμ
μ μ²λ¦¬νλ©΄ μμ
μ΄ λλ λκΉμ§ λ€λ₯Έ μμ
μ μ²λ¦¬νμ§ λͺ»νλ―λ‘, μ 체 μ²λ¦¬ μκ°μ΄ μ€λ κ±Έλ¦¬κ² λμ΄ λΉν¨μ¨μ μ΄κ² λκ² λλ€. λ°λΌμ μ΄λ¬ν κ²½μ°μλ λ°λ‘ λ€μμ λ€λ£° Async Non-Blocking λ°©μμ μ¬μ©νμ¬ μμ
μ μ²λ¦¬νλ κ²μ΄ μ’λ€.
μ μ© νλ‘κ·Έλ¨ μμ
λνμ μΌλ‘ Cλ JAVAμ μ½λ μ€ν ν 컀맨λμμ μ λ ₯μ λ°λ κ²½μ°κ° μ΄μ ν΄λΉλλ€. μ¬μ©μλ‘λΆν° μ λ ₯μ λ°μμΌ κ·Έ μ λ ₯κ°μ κ°μ§κ³ λ΄λΆ μ²λ¦¬λ₯Ό νμ¬ κ²°κ³Όκ°μ μ½μμ μΆλ ₯ν΄μ£ΌκΈ° λλ¬Έμ μμ°¨μ μΈ μμ μ΄ μꡬλλ€. λ΄λΆμ μΌλ‘ λ³Έλ€λ©΄ μ€ν μ½λκ° μ½μμ°½μ λμ°κ³ Please enter your name ν μ€νΈλ₯Ό μΉκ³ λ λ€μ μ¬μ©μμ 리ν΄κ°μ΄ νμνκΈ° λλ¬Έμ μ μ΄κΆμ μμ€ν μμ μ¬μ©μλ‘ λ겨 μ¬μ©μκ° κ°μ μ λ ₯ν λκΉμ§ κΈ°λ€λ¦¬λ κ²μ΄λ€.
Async Non-Blocking μ‘°ν©
Async Non Blocking μ‘°ν©μ λ€λ₯Έ μμ μ΄ μ§νλλ λμμλ μμ μ μμ μ μ²λ¦¬νκ³ (Non Blocking), λ€λ₯Έ μμ μ κ²°κ³Όλ₯Ό λ°λ‘ μ²λ¦¬νμ§ μμ μμ μμκ° μ§μΌμ§μ§ μλ (Async) λ°©μμ΄λ€. λ€λ₯Έ μμ μ κ²°κ³Όκ° μμ μ μμ μ μν₯μ μ£Όμ§ μμ κ²½μ°μ νμ©ν μ μλ€.
μ€μν λμ μμ
- νμ₯ : μ¬μ1μ¨ Aμ λ¬΄μ’ ν΄μ£ΌμΈμ. (λμμ μ§μ)
- νμ₯ : μ¬μ2μ¨ Bμ λ¬΄μ’ ν΄μ£ΌμΈμ. (λμμ μ§μ)
- νμ₯ : μ¬μ3μ¨ Cμ λ¬΄μ’ ν΄μ£ΌμΈμ. (λμμ μ§μ)
- νμ₯ : λ€λ₯ΈμΌμ ν΄μΌμ§ ~
- μ¬μ2 : νμ₯μΈ B λͺ¨λ μ²λ¦¬νμ΅λλ€. (μ 무λμ λ°λΌ κ° μ¬μλ§λ€ μλ£νλ μκ°μ΄ μ κ°κΈ° λ€λ₯Ό μ μλ€)
- μ¬μ1 : νμ₯μΈ A λͺ¨λ μ²λ¦¬νμ΅λλ€.
- μ¬μ3 : νμ₯μΈ C λͺ¨λ μ²λ¦¬νμ΅λλ€.
μ½λ λμ μμ
μμμ νμΌ μ½κΈ° μ½λλ₯Ό Sync Blocking λ°©μμΌλ‘ ꡬννμλλ° μ΄λ₯Ό κ·Έλλ‘ Async Non-Blocking λ°©μμΌλ‘λ μ½λλ₯Ό ꡬνν μ μλ€. Sync Blocking λ°©μκ³Ό λλλ¬μ§ μ°¨μ΄μ μ νΈμΆ ν¨μμ μ½λ°± ν¨μλ₯Ό λ£μλ€λ μ μ΄λ€. μ΄λ₯Ό ν΅ν΄ λΉλκΈ° λ ΌλΈλ‘νΉ λ°©μλλ‘ μ²λ¦¬λ μμ μ κ²°κ³Όλ₯Ό νμ²λ¦¬ ν μ μκ² λλ€. κ·Έλ¦¬κ³ λΉλκΈ° μ΄κΈ° λλ¬Έμ μμ μ μμλ₯Ό κ³ λ €νμ§ μμ λκΈ° λΈλ‘νΉκ³Όλ κ±°κΎΈλ‘ κ°μ₯ λ¨Όμ 'done' μ΄λΌλ μ½μ λ‘κ·Έκ° μ°νκ² λκ³ κ·Έ νμ νμΌ λ΄μ©μ΄ μΆλ ₯λ κ²μ΄λ€.
// λΉλκΈ°μ μΌλ‘ νμΌ μ½κΈ°
const fs = require('fs'); // νμΌ μμ€ν
λͺ¨λ λΆλ¬μ€κΈ°
fs.readFile('file.txt', 'utf8', (err, data) => { // νμΌ μ½κΈ° μμ²κ³Ό μ½λ°± ν¨μ μ λ¬
if (err) throw err; // μλ¬ μ²λ¦¬
console.log(data); // νμΌ λ΄μ© μΆλ ₯
});
fs.readFile('file2.txt', 'utf8', (err, data) => {
if (err) throw err;
console.log(data);
});
fs.readFile('file3.txt', 'utf8', (err, data) => {
if (err) throw err;
console.log(data);
});
console.log('done'); // μμ
μλ£ λ©μμ§ μΆλ ₯
fs.readFileSyncμfs.readFileν¨μλ λλ€ λκ°μ΄ νμΌμ μ½λ ν¨μμ΄μ§λ§ λκΈ°λ λΉλκΈ°λμ λ°λΌ μ°¨μ΄κ° μλ€.
μ¦,fs.readFileSyncν¨μλ λκΈ°μ μΌλ‘ νμΌμ μ½κ³fs.readFileν¨μλ λΉλκΈ°μ μΌλ‘ νμΌμ μ½λλ€.
μ΄μ²λΌ Async Non Blocking μ‘°ν©μ μμ λμ΄ λ§κ±°λ μκ°μ΄ μ€λ 걸리λ μμ μ μ²λ¦¬ν΄μΌ νλ κ²½μ°μ μ ν©νλ€. μλ₯Ό λ€μ΄, λμ©λ λ°μ΄ν°λ₯Ό μ²λ¦¬νκ±°λ λ§μ μμ²μ μ²λ¦¬νλ μλΉμ€μμλ Async Non Blocking λ°©μμ μ¬μ©νμ¬ ν μμ μ΄ μ²λ¦¬λλ λμ λ€λ₯Έ μμ μ μ²λ¦¬ν μ μμΌλ―λ‘ μ 체 μ²λ¦¬ μκ°μ μ€μΌ μ μμ΄ μ΄ν리μΌμ΄μ μ²λ¦¬ μ±λ₯μ ν₯μμν¬ μ μκ² λλ€.
νμ© μμ νλ‘κ·Έλ¨
λΉλκΈ° λ ΌλΈλ‘νΉμ νμ©νλ νλ‘κ·Έλ¨μ λ§μ΄ μλ€. κ·Έμ€ μλ₯Ό λ€μλ©΄, μΉ λΈλΌμ°μ μ νμΌ λ€μ΄λ‘λκ° λΉλκΈ° λ ΌλΈλ‘νΉμ νμ©νλ μμ λΌκ³ ν μ μλ€. μΉ λΈλΌμ°μ λ μΉ μ¬μ΄νΈμμ νμΌμ λ€μ΄λ‘λν λ, νμΌμ μ μ‘μ΄ μλ£λ λκΉμ§ λ€λ₯Έ μμ μ νμ§ μκ³ κΈ°λ€λ¦¬λ κ²μ΄ μλλΌ, λ€λ₯Έ νμ΄λ μ°½μ μ΄κ±°λ μΉ μνμ ν μ μλ€. μ΄λ μΉ λΈλΌμ°μ κ° νμΌ λ€μ΄λ‘λλ₯Ό λΉλκΈ°μ μΌλ‘ μ²λ¦¬νκ³ , μ½λ°± ν¨μλ₯Ό ν΅ν΄ λ€μ΄λ‘λκ° μλ£λλ©΄ μλ €μ£Όλ λ°©μμΌλ‘ ꡬνλμ΄ μκΈ° λλ¬Έμ΄λ€.
Sync Non-Blocking μ‘°ν©
Sync Non-Blocking μ‘°ν©μ λ€λ₯Έ μμ μ΄ μ§νλλ λμμλ μμ μ μμ μ μ²λ¦¬νκ³ (Non Blocking), λ€λ₯Έ μμ μ κ²°κ³Όλ₯Ό λ°λ‘ μ²λ¦¬νμ¬ μμ μ μμ°¨λλ‘ μν νλ (Sync) λ°©μμ΄λ€.
μ€μν λμ μμ
νμ₯μ΄ μ 무 A, B, Cλ₯Ό μ¬μ 1, 2, 3 μκ² μν€λ €κ³ νλ€. κ·Έλ°λ° μ 무 νΉμ±μ μ 무 Aλ₯Ό μλ£ν΄μΌ μ 무 Bλ₯Ό ν μ μκ³ , μ 무 Bλ₯Ό μλ£ν΄μΌ μ 무 Cλ₯Ό ν μ μλ€κ³ νλ€.
- νμ₯ : μ¬μ1μ¨ μ 무 A μ’ ν΄μ£ΌμΈμ
- μ¬μ1 : λ€ μκ² μ΅λλ€. (Aλ₯Ό μ²λ¦¬μ€)
- νμ₯ : λ€μ μ 무 Bλ₯Ό νλ €λ©΄ Aκ° μλ£λμΌ νλλ°.. μ¬μ1μ¨ λ€νμ΄μ?
- μ¬μ1 : μμ§μ΄μ A μ²λ¦¬μ€μ λλ€
- νμ₯ : μ¬μ1μ¨ λ€νμ΄μ?
- μ¬μ1 : μμ§μ΄μ A μ²λ¦¬μ€μ λλ€
- μ¬μ1 : νμ₯λ A λͺ¨λ μλ£νμ΅λλ€
- νμ₯ : μκ³ νμ΄μ. μ¬μ2μ¨ μ 무 Bμ’ ν΄μ£ΌμΈμ.
- μ¬μ2 : λ€ μκ² μ΅λλ€. (Bλ₯Ό μ²λ¦¬μ€)
- νμ₯ : λ€μ μ 무 Cλ₯Ό νλ €λ©΄ Bκ° μλ£λμΌ νλλ°.. μ¬μ2μ¨ λ€νμ΄μ?
- ...μλ΅
μ½λ λμ μμ
λκΈ° + λ ΌλΈλ‘νΉ μ½λλ₯Ό νννλλ° μ ν©ν λμ€μ μΈ μΈμ΄λ‘ μλ°(Java)λ₯Ό λ€ μμλ€. μ€λ λ(Thread) κ°μ²΄λ₯Ό λ§λ€μ΄ μμ² μμ μ λ°±κ·ΈλΌμ΄λμ λκ² νκ³ λ©μΈ λ©μλμμ whileλ¬Έμ ν΅ν΄ μ€λ λκ° λͺ¨λ μ²λ¦¬λμλμ§ λμμμ΄ νμΈνκ³ , μ²λ¦¬κ° μλ£λλ©΄ λ€μ λ©μΈ μμ μ μννλ€.
// Runnable μΈν°νμ΄μ€λ₯Ό ꡬννλ ν΄λμ€ μ μ
class MyTask implements Runnable {
@Override
public void run() {
// λΉλκΈ°λ‘ μ€νν μμ
System.out.println("Hello from a thread!");
}
}
public class Main {
public static void main(String[] args) {
// Thread κ°μ²΄ μμ±
Thread thread = new Thread(new MyTask());
// μ€λ λ μ€ν
thread.start();
// Non-Blockingμ΄λ―λ‘ λ€λ₯Έ μμ
κ³μ κ°λ₯
System.out.println("Main thread is running...");
// Syncλ₯Ό μν΄ μ€λ λμ μμ
μλ£ μ¬λΆ νμΈ
while (thread.isAlive()) {
System.out.println("Waiting for the thread to finish...");
}
System.out.println("Thread finished!");
System.out.println("Run the next tasks");
}
}
λΆλͺ μ€λ λλ₯Ό μ΄μ©νμ¬ μμ μ λ³λ ¬μ μΌλ‘ μ²λ¦¬νλλ‘ μ§μνμ§λ§, λ©μΈ μ½λμ whileλ¬Έμ μνν¨μΌλ‘μ μμ²ν μμ μ μλ£ μ¬λΆλ₯Ό κ³μ νμΈνκ³ κ²°κ³Όμ μΌλ‘ κ²°κ΅ λκΈ°μ μΌλ‘ μμ μ μμλλ‘ μνλ¨μ λ³Ό μ μλ€.
μλ°μ€ν¬λ¦½νΈ(Javascript) κ²½μ°μλ λκΈ° + λ
ΌλΈλ‘νΉ μ½λλ₯Ό ꡬννκΈ°μλ μ§μνλ λ©μλμ νκ³κ° μμ΄ μλ²½ν ννν μλ μλ€. λ€λ§ μ΄μ λΉμ·νκ² ννν μ μλ κΈ°λ²μ΄ μλ λ° λ°λ‘ async/await ν€μλ μ΄λ€. κΈ°λ³Έμ μΌλ‘ Promise.then νΈλ€λ¬ λ°©μμ λΉλκΈ° λ
ΌλΈλ‘νΉ λ°©μμ΄λΌ λ³Ό μ μλ€. μ΄λ λΉλκΈ° μμ
λ€ κ°μ μμκ° μ€μνλ€λ©΄ await ν€μλλ₯Ό ν΅ν΄ λκΈ°μ μΌλ‘ μ²λ¦¬ν΄ μ€ μ μλ€.
μλ₯Ό λ€μ΄ Node.jsμμ μ¬λ¬κ°μ νμΌμ μ½μ΄μ λ΄μ©μ λΉκ΅νλ μμ μ νλ€κ³ κ°μ ν΄λ³΄μ. μ΄λ₯Ό Sync Non-Blocking λ°©μμΌλ‘ μμ±νλ€λ©΄, μΈ νμΌμ λμμ μ½κΈ° μμνκ³ (Non Blocking), λ νμΌμ μ½κΈ°κ° λͺ¨λ μλ£λλ©΄ λ΄μ©μ λΉκ΅νλ νμ²λ¦¬λ₯Ό μ§ννλ€ (Sync).
const fs = require('fs');
const { promisify } = require('util'); // μ νΈλ¦¬ν° λͺ¨λ λΆλ¬μ€κΈ°
const readFileAsync = promisify(fs.readFile); // fs.readFile ν¨μλ₯Ό Promise κ°μ²΄λ₯Ό λ°ννλ ν¨μλ‘ λ³ν
async function readFiles() {
try {
// Promise.all() λ©μλλ₯Ό μ¬μ©νμ¬ μ¬λ¬ κ°μ λΉλκΈ° μμ
μ λ³λ ¬λ‘ μ²λ¦¬ν©λλ€. (λΉλκΈ° λ
ΌλΈλ‘νΉ)
const [data1, data2, data3] = await Promise.all([
readFileAsync('file.txt', 'utf8'), // file.txt νμΌμ μ½μ΅λλ€.
readFileAsync('file2.txt', 'utf8'), // file2.txt νμΌμ μ½μ΅λλ€.
readFileAsync('file3.txt', 'utf8') // file3.txt νμΌμ μ½μ΅λλ€.
]);
// νμΌ μ½κΈ°κ° μλ£λλ©΄ dataμ νμΌ λ΄μ©μ΄ λ€μ΄μ΅λλ€.
console.log(data1); // file.txt νμΌ λ΄μ©μ μΆλ ₯ν©λλ€.
console.log(data2); // file2.txt νμΌ λ΄μ©μ μΆλ ₯ν©λλ€.
console.log(data3); // file3.txt νμΌ λ΄μ©μ μΆλ ₯ν©λλ€.
// νμΌ λΉκ΅ λ‘μ§ μ€ν...
} catch (err) {
throw err;
}
}
readFiles(); // async ν¨μλ₯Ό νΈμΆ
async/awaitμ λΉλκΈ° λ ΌλΈλ‘νΉ λ°©μμ λκΈ° λ ΌλΈλ‘νΉ λ°©μμΌλ‘ λ°κΏμ£Όλ κΈ°λ²μ΄λΌκ³ ν μ μμ§λ§, κ·Έλ¬λ async/awaitμ λ΄λΆμ μΌλ‘λ μ¬μ ν λΉλκΈ° λ ΌλΈλ‘νΉ λ°©μμΌλ‘ λμνλ€λ μ μ μ μνμ. async ν¨μ μμ²΄κ° λ©μΈ μ½ μ€ν(call stack)μ΄ λͺ¨λ μ€νλμ΄ λΉμμ ΈμΌ μννκΈ° λλ¬Έμ λΉλκΈ° λ ΌλΈλ‘νΉμ΄κΈ° λλ¬Έμ΄λ€.
νμ© μμ νλ‘κ·Έλ¨
λκΈ° λ ΌλΈλ‘νΉμ ννμ§ μλ μΌμ΄μ€μ΄μ§λ§ κ·Έλλ μ΄λ₯Ό ννν μ μλ νλ‘κ·Έλ¨μ΄ μλ€. κ²μμμ 맡μ μ΄λν λλ₯Ό μκ°ν΄λ³΄μ. μ°μ 맡 λ°μ΄ν°λ₯Ό λͺ¨λ λ€μ΄λ‘λ ν΄μΌ ν κ²μ΄λ€. κ·Έλμ νλ©΄μλ λ‘λ© μ€ν¬λ¦°μ΄ λ¬λ€. μ΄ λ‘λ© μ€ν¬λ¦°μ λ‘λ©λ°κ° μ±μμ§λ νλ‘κ·Έλ¨μ΄ μννκ³ μλ κ²μ΄λ€. μ¦, μ μ΄κΆμ μ¬μ ν λνν μμ΄ νλ©΄μ λ‘λμ¨μ΄ νμλλ κ²μ΄λ€. κ·Έλ¦¬κ³ λμμμ΄ λ§΅ λ°μ΄ν°κ° μ΄λμ λ λ‘λκ° λ¬λμ§ λμμμ΄ μ‘°ννλ€. μμ μ μμ μ κ³μνκ³ μμ§λ§ λ€λ₯Έ μμ κ³Όμ λκΈ°λ₯Ό μν΄ κ³μν΄μ λ€λ₯Έ μμ μ΄ λλ¬λμ§ μ‘°ννλ κ²μ΄λ€.
Sync Blocking vs Sync Non-Blocking
κ·Έλ°λ° κ°λ§ν 보면 λΈλ‘νΉμ΄λ λ ΌλΈλ‘νΉμ΄λ λ©μΈ ν¨μμμ κ²°κ΅μ μ½λλ₯Ό μμ°¨μ μΌλ‘ μννκΈ° λλ¬Έμ μ 체 μμ μ μ΅μ’ κ±Έλ¦° μκ°μ λμ΄ μ°¨μ΄κ° μμ΄ λ³΄μΈλ€. κ·ΈλΌ λ λ°©μμ λκΈ΄κ°κΈ΄μΈ κ²μΈκ°?
μ±λ₯ μ°¨μ΄λ μν©μ λ°λΌ λ€λ₯΄κ² μ§λ§, μΌλ°μ μΌλ‘ λκΈ° + λ ΌλΈλ‘νΉμ΄ λκΈ° + λΈλ‘νΉλ³΄λ€ ν¨μ¨μ μΌ μ μλ€. μλνλ©΄ λκΈ° + λ ΌλΈλ‘νΉμ νΈμΆνλ ν¨μκ° μ μ΄κΆμ κ°μ§κ³ μμ΄μ λ€λ₯Έ μμ μ λ³λ ¬μ μΌλ‘ μνν μ μκΈ° λλ¬Έμ΄λ€. λ°λ©΄μ λκΈ° + λΈλ‘νΉμ νΈμΆνλ ν¨μκ° μ μ΄κΆμ μμ΄μ λ€λ₯Έ μμ μ μνν μ μκΈ° λλ¬Έμ λλ€
κ²μ λ‘λ© νλ©΄κ³Ό λλΆμ΄ λκΈ° + λ ΌλΈλ‘νΉμ λλ€λ₯Έ μμ λ‘λ λΈλΌμ°μ μμ νμΌμ λ€μ΄λ‘λνλ©΄ λνλλ λ€μ΄λ‘λ μ§νλ°λ₯Ό λ€ μ κ° μλ€.
μΉλΈλΌμ°μ μμ νμΌμ λ€μ΄λ‘λ ν κ²½μ° μμ μ μΉλΈλΌμ°μ μ Web APIs μΌλ‘ μμ μ λ°±κ·ΈλΌμ΄λλ‘ λκΈ°κ³ 'μ μ΄κΆ'μ λ°λ‘ λ°νλ°μ λ€λ₯Έ μμ μ μνν μ μλ€. μ΄κ²μ΄ Non Blocking μ΄λ€.
κ·Έλ°λ° μΉλΈλΌμ°μ λ νμΌ λ€μ΄λ‘λ μμ μ μλ£ μ¬λΆμ κ΄μ¬μ΄ μλ€. μ¦, λ€μ΄λ‘λ μμ μ΄ μΈμ λλκ³ μΌλ§λ μ§νλμλμ§ νμΌ λ€μ΄λ‘λ λ‘λμ¨μ λΈλΌμ°μ νλ¨λ°μ νμν΄μ€λ€. κ·Έλ¦¬κ³ νμΌμ΄ λͺ¨λ λ€μ΄λ‘λ μλ£λλ©΄ μ¬μ©μκ° μνλ μ΅μ’ μμ μΈ νμΌ λ€μ΄λ‘λ μμ μ μννκ² λλ€. μ΄κ²μ΄ Synchronous μ΄λ€.
μ΄λ μ°λ¦¬λ νμΌμ λ€μ΄λ‘λ νλ©΄μ μΉμνμ νκ±°λ μ νλΈ μμ μ λ€μ μ μλ€. μ μ΄κΆμ κ°μ§κ³ μκΈ° λλ¬Έμ λΈλΌμ°μ κ° λ©ν° νμ€νΉμ νλλ‘ μ μ ν μ½λλ₯Ό ꡬννμκΈ° λλ¬Έμ κ°λ₯ν κ²μ΄λ€. λ°λΌμ λκΈ° + λ ΌλΈλ‘νΉ λ°©μμ μΌλ°μ μΈ λκΈ° + λΈλ‘νΉ λ°©μλ³΄λ€ κ΅¬νμ λ°λΌ λ ν¨μ¨μ μΌλ‘ μμ μ μ²λ¦¬ ν μ μλ€κ³ λ³Ό μ μλ€. (μλ°μ€ν¬λ¦½νΈμ async/await μΌλ‘ μμνλ©΄ μ€νλ € μ΄ν΄κ° μλ μκ° μλ€. μλ°μ μ€λ λ κ°μ²΄λ‘ μμνμ)
Async Blocking μ‘°ν©
Async Blocking μ‘°ν©μ λ€λ₯Έ μμ μ΄ μ§νλλ λμ μμ μ μμ μ λ©μΆκ³ κΈ°λ€λ¦¬λ (Blocking), λ€λ₯Έ μμ μ κ²°κ³Όλ₯Ό λ°λ‘ μ²λ¦¬νμ§ μμ μμλλ‘ μμ μ μννμ§ μλ (Async) λ°©μμ΄λ€. Async-blocking μ κ²½μ°λ μ€λ¬΄μμ μ λ§μ£ΌνκΈ° μ½μ§ μμ λ€λ£°μΌμ΄ κ±°μ μλ€. κ·Έλμ κ·Έλ₯ λμ΄κ°λ ν¬κ² λ¬Έμ λ μλ€.
Async Blocking vs Sync Blocking
μ μ¬μ§λ§ 보λλΌλ μμ Sync-blocking μν κ·Έλ¦Όκ³Ό ν° μ°¨μ΄κ° μμ΄ λ³΄μΈλ€. μ€μ λ‘ λ μλΆμ΄ λλ κ·Έλλ‘ κ°λ μ μΌλ‘ μ°¨μ΄κ° μμ λΏμ΄μ§ μ λ§λ‘ μ±λ₯μ μΌλ‘ μ°¨μ΄κ° μλ€.
λ³΄ν΅ Async-blockingμ κ°λ°μκ° λΉλκΈ° λ ΌλΈλ‘νΉμΌλ‘ μ²λ¦¬ νλ €λ€κ° μ€μνλ κ²½μ°μ λ°μνκ±°λ, μκΈ°λ λͺ¨λ₯΄κ² λΈλ‘νΉ μμ μ μ€ννλ μλμΉ μμ κ²½μ°μ μ¬μ©λλ€. κ·Έλμ μ΄ λ°©μμ μν° ν¨ν΄(anti-pattern)μ΄λΌκ³ μΉλΆνκΈ°λ νλ€.
νμ© μμ νλ‘κ·Έλ¨
λ€λ§ Async Blocking μ΄ μ€μ λ‘ μ μ©λ μ€λ¬΄ μ¬λ‘κ° μκΈ΄ νλ€. Node.js + MySQLμ μ‘°ν©μ΄ λνμ μΈλ°, Node.jsμμ λΉλκΈ° λ°©μμΌλ‘ λ°μ΄ν°λ² μ΄μ€μ μ κ·ΌνκΈ° λλ¬Έμ Async μ΄μ§λ§, MySQL λ°μ΄ν°λ² μ΄μ€μ μ κ·ΌνκΈ° μν MySQL λλΌμ΄λ²κ° λΈλ‘νΉ λ°©μμΌλ‘ μλλκΈ° λλ¬Έμ΄λ€.
- JavaScriptλ λΉλκΈ° λ°©μμΌλ‘ MySQLμ 쿼리λ₯Ό 보λΈλ€. (Async)
- MySQLμ 쿼리λ₯Ό μ²λ¦¬νλ©΄μ JavaScriptμκ² μ μ΄κΆμ λκ²¨μ£Όμ§ μλλ€. (Blocking)
- κ·Έλ¬λ©΄ JavaScriptλ λ€λ₯Έ μμ μ κ³μ μνν μ μμ§λ§, MySQLμ κ²°κ³Όκ°μ νμλ‘ νκΈ° λλ¬Έμ MySQLμ΄ μΏΌλ¦¬λ₯Ό μλ£ν λκΉμ§ κΈ°λ€λ €μΌ λλ€.
- κ²°κ΅ Sync Blockingκ³Ό μμ μνμ μ°¨μ΄κ° μκ² λλ€.
μ΄λ κ² JavaScriptμ MySQLμ μ‘°ν©μ λΉλκΈ°μ μ΄λ©΄μλ λΈλ‘νΉλλ Async Blocking μ‘°ν©μ΄λΌκ³ ν μ μλ€. μ΄λ¬ν μ€λ¬ν μ‘°ν©μ μ€νλ € κ°λ°μμκ² νΌλλ§ μΌμΌν€κΈ° λλ¬Έμ κ·Έλμ μ€λ¬΄μμλ Node.js μλ² νλ‘κ·Έλλ°ν λ μμ async/awaitλ‘ λκΈ° μ²λ¦¬λ₯Ό νλ νΈμ΄λ€.
const mysql = require('mysql');
// connectDB ν¨μλ₯Ό μ μ
async function connectDB () {
// DB μ°κ²° μ 보λ₯Ό λ΄μ κ°μ²΄ μμ±
let connectionInfo = {
host: 'localhost', // DB νΈμ€νΈ μ£Όμ
user: 'root', // DB μ μ μ΄λ¦
password: '1234', // DB λΉλ°λ²νΈ
database: 'spyncdb' // DB μ΄λ¦
};
// connection κ°μ²΄λ₯Ό μμ±νκ³ λ°ν
let connection = mysql.createConnection(connectionInfo);
return connection;
}
// mysql λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©νλ κ²½μ°
async function userHandler (username, displayName, profilePicture, email) {
// DBμ μ°κ²°
connection = await connectDB()
// DBλ₯Ό μ ν
await connection.query ('USE spyncdb;');
// 쿼리λ₯Ό μ€ννκ³ κ²°κ³Όλ₯Ό λ°μ
let result = await connection.query ('SELECT * FROM users WHERE username = ?', [username]);
}
// userHandler ν¨μλ₯Ό νΈμΆνκ³ user_id κ°μ μ»μΌλ €κ³ ν¨
let user_id = await userHandler (aUser.username, aUser.displayName, aUser.profilePicture, aUser.email); // userHandler ν¨μκ° λΉλκΈ° μμ
μ μλ£ν λκΉμ§ κΈ°λ€λ¦Ό
console.log (user_id); // user_id μΆλ ₯
# μ°Έκ³ μλ£
https://medium.com/from-the-scratch/wtf-is-synchronous-and-asynchronous-1a75afd039df
https://notes.arkalim.org/notes/programming/asynchronous%20programming/
https://www.youtube.com/watch?v=oEIoqGd-Sns
https://joooing.tistory.com/entry/%EB%8F%99%EA%B8%B0%EB%B9%84%EB%8F%99%EA%B8%B0-%EB%B8%94%EB%A1%9C%ED%82%B9%EB%85%BC%EB%B8%94%EB%A1%9C%ED%82%B9
https://velog.io/@ellyheetov/Asynchoronous-VS-Synchoronous-1
https://velog.io/@nittre/%EB%B8%94%EB%A1%9C%ED%82%B9-Vs.-%EB%85%BC%EB%B8%94%EB%A1%9C%ED%82%B9-%EB%8F%99%EA%B8%B0-Vs.-%EB%B9%84%EB%8F%99%EA%B8%B0
https://ttl-blog.tistory.com/782