The JavaScript Event Loop - Lee-hyuna/33-js-concepts-kr GitHub Wiki
The JavaScript Event Loop
μ΄λ²€νΈ 루νλ μλ° μ€ν¬λ¦½νΈλ₯Ό μ΄ν΄νλ λ° κ°μ₯ μ€μν μμ μ€ νλμ λλ€. μ΄ κ²μλ¬Όμ κ°λ¨ν μ©μ΄λ‘ μ€λͺ ν©λλ€.
λ²μ : https://flaviocopes.com/javascript-event-loop/
Introduction
μ΄λ²€νΈ 루νλ μλ° μ€ν¬λ¦½νΈλ₯Ό μ΄ν΄νλ λ° κ°μ₯ μ€μν μμ μ€ νλμ λλ€.
νμλ JavaScriptλ‘ μλ κ° νλ‘κ·Έλλ° ν΄μμ§λ§, νλμμ μ΄λ»κ² μλνλμ§ μμ ν μ΄ν΄νμ§ λͺ»νμ΅λλ€. μ΄ κ°λ μ μμΈν μμ§ λͺ»νλ κ²μ μμ ν λ©μ§μ§λ§ νμμ κ°μ΄ μ΄λ»κ² μλνλμ§ μλ©΄ λμμ΄λ©λλ€. λνμ΄ μμ μμ μ’ κΆκΈν΄ ν μλ μμ΅λλ€.
μ΄ κΈμ μλ° μ€ν¬λ¦½νΈκ° λ¨μΌ μ€λ λλ‘ μ΄λ»κ² μλνλμ§, κ·Έλ¦¬κ³ λΉλκΈ° ν¨μλ₯Ό μ²λ¦¬νλ λ°©λ²μ λν΄ μ€λͺ ν©λλ€.
JavaScript μ½λλ λ¨μΌ μ€λ λλ‘ μ€νλ©λλ€. ν λ²μ ν κ°μ§ μΌμ΄ λ°μν©λλ€.
μ΄λ λμμ± λ¬Έμ μ λν΄ κ±±μ νμ§ μκ³ νλ‘κ·Έλλ°νλ λ°©λ²μ λ¨μννλ―λ‘ μ€μ λ‘ λ§€μ° μ μ©ν©λλ€.
μ½λ μμ± λ°©λ²μ μ£Όμλ₯Ό κΈ°μΈμ¬μΌνλ©° λκΈ°μ λ€νΈμν¬ νΈμΆμ΄λ 무ν 루νμ κ°μ΄ μ€λ λλ₯Ό μ°¨λ¨ν μμλ μμλ νΌνμμμ€.
μΌλ°μ μΌλ‘ λͺ¨λ λΈλΌμ°μ νμ λν μ΄λ²€νΈ 루νκ°μμ΄ λͺ¨λ νλ‘μΈμ€λ₯Ό 격리νκ³ λ¬΄ν 루ν λλ λ¬΄κ±°μ΄ μ²λ¦¬κ°μλ μΉ νμ΄μ§κ° μ 체 λΈλΌμ°μ λ₯Ό block μν€λ κ²μ νΌν μ μμ΅λλ€.
μ΄ νκ²½μ μ¬λ¬ κ°μ λμμ±(concurrent) μ΄λ²€νΈ 루νλ₯Ό κ΄λ¦¬ν©λλ€. μλ₯Ό λ€μ΄ API νΈμΆμ λ€λ£Ήλλ€. μΉ μ컀λ μ체 μ΄λ²€νΈ 루νμμ μ€νλ©λλ€.
μ£Όλ‘ μ½λκ° λ¨μΌ μ΄λ²€νΈ 루νμμ μ€νλκ³ μ½λλ₯Ό μ°¨λ¨νμ§ μλλ‘μ΄ μ½λλ₯Ό μΌλμ λμ΄μΌν©λλ€.
Blocking the event loop
μ΄λ²€νΈ 루νλ‘ μ»¨νΈλ‘€μ λλ리기 μν΄ λ무 μ€λ 걸리λ JavaScript μ½λλ νμ΄μ§μ λͺ¨λ JavaScript μ½λ μ€νμ μ°¨λ¨νκ³ UI μ€λ λλ₯Ό μ°¨λ¨νλ©° μ¬μ©μλ ν΄λ¦νκ±°λ νμ΄μ§λ₯Ό μ€ν¬λ‘€ ν μ μμ΅λλ€.
JavaScriptμ κ±°μ λͺ¨λ I / O ν리미ν°λΈλ λΉ λΈλ‘νΉμ λλ€. λ€νΈμν¬ μμ², Node.js νμΌ μμ€ν μμ λ±. μ΄λ° λΈλ‘νΉμ΄ μμΈμ΄λ―λ‘ JavaScriptλ μ½λ°±μ κΈ°λ°νκ³ μμΌλ©°, μ΅κ·Όμλ promises λ° async/await μ κΈ°λ°ν©λλ€.
The call stack
νΈμΆ μ€νμ LIFO λκΈ°μ΄ (λ§μ§λ§ λ€μ΄κ°κ³ , 첫λ²μ§Έκ° λμ¨λ€.)μ λλ€.
μ΄λ²€νΈ 루νλ νΈμΆ μ€νμ κ³μ κ²μ¬νμ¬ μ€νν΄μΌνλ functionμ΄ μλμ§ νμΈν©λλ€.
κ·Έλ κ²νλ λμ νΈμΆ μ€νμ μ°Ύμ λͺ¨λ ν¨μ νΈμΆμ μΆκ°νκ³ κ°κ°μ μμλλ‘ μ€νν©λλ€.
λλ²κ±° λλ λΈλΌμ°μ μ½μμμ μ΅μν μ€λ₯ μ€ν μΆμ μ μκ³ μμ΅λκΉ? λΈλΌμ°μ λ νΈμΆ μ€νμμ ν¨μ μ΄λ¦μ μ°Ύμ μ΄λ€ ν¨μκ° νμ¬ νΈμΆμ μμνλμ§ μλ €μ€λλ€.
A simple event loop explanation
μμ λ₯Ό μ νν΄ λ³΄κ² μ΅λλ€.
λλ
foo
,bar
μbaz
λ₯Ό _random names_λ‘ μ¬μ©ν©λλ€. κ·Έλ€μ λ체 ν μ΄λ¦μ μ λ ₯νμμμ€
const bar = () => console.log('bar')
const baz = () => console.log('baz')
const foo = () => {
console.log('foo')
bar()
baz()
}
foo()
νλ¦°νΈ λκ±°λ μλμ κ°λ€.
foo
bar
baz
μ΄λ κ² λ κ²μ΄λ€.
μ΄ μ½λκ° μ€νλλ©΄, λ¨Όμ foo ()
κ° νΈμΆλ©λλ€. foo ()
λ΄λΆμμ λ¨Όμ bar ()
λ₯Ό νΈμΆ ν λ€μbaz ()
λ₯Ό νΈμΆν©λλ€.
μ΄ μμ μμ νΈμΆ μ€νμ λ€μκ³Ό κ°μ΅λλ€.
λͺ¨λ λ°λ³΅μμ μ΄λ²€νΈ 루νλ νΈμΆ μ€νμ 무μΈκ°κ° μλμ§ μ°Ύμμ μ€νν©λλ€.
μ½ μ€νμ΄ λΉμ΄μ§λ κΉμ§ μ€νλλ€.
Queuing function execution
μμ μλ μ μμ μΌλ‘ 보μ λλ€. νΉλ³ν κ²μ μμ΅λλ€. JavaScriptλ μ€νν΄μΌ ν κ²μ μ°Ύκ³ , μμλλ‘ μ€νν©λλ€.
μ€νμ΄ κΉ¨λν΄μ§ λκΉμ§ ν¨μλ₯Ό μ°κΈ°νλ λ°©λ²μ μ΄ν΄ λ³΄κ² μ΅λλ€.
`setTimeout (() => {}), 0)μ μ μ€ μΌμ΄μ€λ ν¨μλ₯Ό νΈμΆνλ κ²μ΄μ§λ§, μ½λμ λ€λ₯Έ λͺ¨λ ν¨μκ° μ€νλλ©΄ ν¨μλ₯Ό νΈμΆνλ κ²μ΄λ€.
μ΄ μμ λ₯Ό 보μ.
const bar = () => console.log('bar')
const baz = () => console.log('baz')
const foo = () => {
console.log('foo')
setTimeout(bar, 0)
baz()
}
foo()
μ΄ μ½λλ μλ§ λλκ² μΈμ ν μ μμ΅λλ€.
foo
baz
bar
μ΄ μ½λκ° μ€νλλ©΄ λ¨Όμ foo ()κ° νΈμΆλ©λλ€. foo () λ΄λΆμμ μ°λ¦¬λ λ¨Όμ bar
λ₯Ό μΈμλ‘ μ λ¬νμ¬ setTimeoutμ νΈμΆνκ³ νμ΄λ¨Έκ° 0μ΄ λ λκΉμ§ κ°λ₯ν ν 빨리 μ€ννλλ‘ μ§μν©λλ€. κ·Έλ° λ€μ baz ()λ₯Ό νΈμΆν©λλ€.
μ΄ μμ μμ νΈμΆ μ€νμ λ€μκ³Ό κ°μ΅λλ€.
λ€μμ νλ‘κ·Έλ¨μ λͺ¨λ ν¨μμ λν μ€ν μμμ λλ€.
μ μ΄λ° μΌμ΄ λ°μν κΉμ?
The Message Queue
setTimeout ()μ΄ νΈμΆλλ©΄ Browser λλ Node.jsκ° νμ΄λ¨Έλ₯Ό μμν©λλ€. νμ΄λ¨Έκ° λ§λ£λλ©΄μ΄ κ²½μ° μ¦μ 0μΌλ‘ μ€μ νμ¬ μ½λ°± ν¨μκ° Message Queueμ μ μ₯λ©λλ€.
Message Queueλ ν΄λ¦ μ΄λ²€νΈ λ ν€λ³΄λ μ΄λ²€νΈ λλ μλ΅ κ°μ Έ μ€κΈ°μ κ°μ μ¬μ©μκ° μμν μ΄λ²€νΈκ° μ½λμ μλ΅ ν κΈ°νκ° μ€κΈ° μ μ λκΈ°ν©λλ€. λλ onLoadμ κ°μ DOM μ΄λ²€νΈ.
루νλ νΈμΆ μ€νμ μ°μ μμλ₯Ό λΆμ¬νκ³ νΈμΆ μ€νμμ μ°Ύμ λͺ¨λ κ²μ λ¨Όμ μ²λ¦¬νκ³ κ±°κΈ°μ μ무 κ²λ μμΌλ©΄ λ©μμ§ λκΈ°μ΄μμ νλͺ©μ μ νν©λλ€.
μ°λ¦¬λ setTimeout, fetch λλ λ€λ₯Έ κ²λ€μ λΈλΌμ°μ κ° μ 곡νκΈ° λλ¬Έμ μμ μ μμ μ μν ν λκΉμ§ κΈ°λ€λ¦΄ νμκ° μμ΅λλ€. μλ₯Ό λ€μ΄, setTimeout μκ° μ΄κ³Όλ₯Ό 2 μ΄λ‘ μ€μ νλ©΄ 2 μ΄λ₯Ό κΈ°λ€λ¦΄ νμκ° μμ΅λλ€. λκΈ°λ λ€λ₯Έ κ³³μμ λ°μν©λλ€.
ES6 Job Queue
ECMAScript 2015λ Promisesκ° μ¬μ©νλ μμ λκΈ°μ΄ κ°λ μ λμ νμ΅λλ€ (ES6 / ES2015μμλ μκ° λ¨). μ΄κ²μ νΈμΆ μ€νμ λμ λ기보λ€λ κ°λ₯ν ν 빨리 λΉλκΈ° ν¨μμ κ²°κ³Όλ₯Ό μ€ννλ λ°©λ²μ λλ€.
νμ¬ ν¨μκ° λλκΈ° μ μ ν΄κ²°λλ μ½μμ νμ¬ ν¨μ λ°λ‘ λ€μμ μ€νλ©λλ€.
λλ μ μμ§μμ λ‘€λ¬ μ½μ€ν° νκΈ°μ λΉμ λ₯Ό μ μ°Ύμμ΅λλ€. λ©μμ§ νλ λκΈ°μ΄μ λ€μͺ½μ, λ€λ₯Έ λͺ¨λ μ¬λλ€ λ€μμ λΉμ μ κΈ°λ€λ¦½λλ€. λΉμ μ μ°¨λ‘λ₯Ό κΈ°λ€λ €μΌνλ©°, μμ λκΈ°μ΄μ ν¨μ€νΈ ν¨μ€ ν°μΌμ λλ€ λΉμ μ΄ μ΄μ μ κ²μ λλ΄ μλ§μ λΉμ μ λ€λ₯Έ νλ κ²μ 곧 μ·¨ν μμλ€.
const bar = () => console.log('bar')
const baz = () => console.log('baz')
const foo = () => {
console.log('foo')
setTimeout(bar, 0)
new Promise((resolve, reject) =>
resolve('should be right after baz, before bar')
).then(resolve => console.log(resolve))
baz()
}
foo()
μΆλ ₯μ λ€μκ³Ό κ°λ€
foo
baz
should be right after baz, before bar
bar
μ΄λ promises (μ½μμ κΈ°λ°ν Async / await)μ setTimeout () λλ λ€λ₯Έ νλ«νΌ APIλ₯Ό ν΅ν νλ²ν μ€λλ λΉλκΈ° ν¨μμ ν° μ°¨μ΄μ μ λλ€.