[JavaScript] μλ°μ€ν¬λ¦½νΈμμ λΉλκΈ° μ²λ¦¬ ν¨ν΄μ λν΄μ μμλ΄ μλ€. (Callback, Promise, Generator, async/await)
π λ€μ΄κ°λ©°
λΉλκΈ° μ²λ¦¬ ν¨ν΄μ μμ보기 μμ, λΉλκΈ° μ²λ¦¬λ 무μμΌκΉμ?
λΉλκΈ° μ²λ¦¬λ?
νΉμ μ½λμ μ°μ°μ΄ μλ£λ λκΉμ§ μ 체 μ½λμ μ€νμ μ€λ¨νμ§ μκ³ , λ€μ μ½λλ₯Ό μ°μ μ μΌλ‘ μ€ννλ λ°©μμ λ§ν©λλ€.
μ΄λ κ² λμνλ ν¨μλ₯Ό μλ°μ€ν¬λ¦½νΈμμλ 'λΉλκΈ° ν¨μ'λΌκ³ ν©λλ€.
λΉλκΈ° μ²λ¦¬μ νκ³μ μ μμ μλ£ μμ μ μμΈ‘νκΈ° μ΄λ ΅λ€λ μ μ λλ€.
νμ§λ§ μ΄κ²μ λΉλκΈ° μ²λ¦¬μ λ³Έμ§μ μΈ νΉμ±μ΄λ©°, μ΄λ₯Ό ν¨κ³Όμ μΌλ‘ κ΄λ¦¬νλ κ²μ΄ μ€μν©λλ€.
μλ°μ€ν¬λ¦½νΈλ κΈ°λ³Έμ μΌλ‘ μ±κΈ μ€λ λ(single-threaded) κΈ°λ°μ μΈμ΄λ‘, ν λ²μ νλμ μμ λ§ μ²λ¦¬ν μ μμ΅λλ€.
μ¦, μλ°μ€ν¬λ¦½νΈλ μ½λκ° μμ±λ μμλλ‘, μμμ μλλ‘, λκΈ°μ μΌλ‘ μ²λ¦¬λλ€λ κ²μ μλ―Έν©λλ€.
κ·Έλ λ€λ©΄ μ΄λ»κ² μλ°μ€ν¬λ¦½νΈκ° λΉλκΈ°μ μΈ λμμ κ°λ₯νκ² ν μ μμκΉμ?
μ΄μ λν μμΈν λ΄μ©μ ν΄λΉ κΈ(Event Loop)μ μ°Έκ³ ν΄ μ£ΌμΈμ.
μ΄λ² ν¬μ€ν μ μ λͺ© κ·Έλλ‘ λΉλκΈ°λ₯Ό μ²λ¦¬νλ ν¨ν΄μ λν΄μ μμ보λ μκ°μ κ°μ΅λλ€.
λΉλκΈ°λ₯Ό μ²λ¦¬νλ ν¨ν΄μλ μλμ κ°μ΄ μμ΅λλ€.
- μ½λ°±(Callback) ν¨μ
- νλ‘λ―Έμ€(Promise)
- μ λλ μ΄ν°(Generator)
- async/await
μ ν¨ν΄λ€μ λν΄μ μ΄λ»κ² μ¬μ©λκ³ μ λ±μ₯νλμ§ μμλ΄ μλ€.
λΉλκΈ° μ²λ¦¬ ν¨ν΄ β
μ½λ°±(Callback) ν¨μ ν¨ν΄ π‘
λ¨Όμ , μ½λ°±ν¨μλ μ΄λ€ ν¨μμ μΈμλ‘ μ λ¬λλ ν¨μλ₯Ό μλ―Έν©λλ€.
μ΄λ¬ν μ½λ°± ν¨μλ νΉν λΉλκΈ° μ²λ¦¬λ₯Ό μν΄ μ¬μ©λλ©°, μ΄ κ²½μ° λΉλκΈ° μ½λ°±μ΄λΌκ³ λΆλ¦½λλ€.
μ½λ°± ν¨μ ν¨ν΄
νΉμ μ°μ°μ΄ μλ£λ μ΄νμ μ€νλ μ½λλ₯Ό ν¨μ ννλ‘ μ μνλ λ°©μμ λλ€.
κ·Έλμ μ΄λ¬ν λ°©μμ μλ°μ€ν¬λ¦½νΈμ μ΄κΈ° μμ λΆν° λ리 μ¬μ©λμ΄ μμ΅λλ€.
μ½λ°± ν¨μ μμ
μ°λ¦¬λ 3μ΄κ° 걸리λ μμ μ΄ μλ€κ³ κ°μ ν©λλ€.
setTimeoutν¨μλ₯Ό μ΄μ©ν΄μ ν΄λΉ μμ μ΄ μλ£λ ν λ€μ μ½λλ₯Ό λμνλλ‘ νκ³ μΆμ΅λλ€.
function getData() {
setTimeout(() => {
console.log('λ°μ΄ν°λ₯Ό λ°μμ΅λλ€.');
}, 3000);
}
getData();
console.log('μμ
μ΄ λλ¬μ΅λλ€!');
// μΆλ ₯ μμ
// 1. 'μμ
μ΄ λλ¬μ΅λλ€!'
// 2. 'λ°μ΄ν°λ₯Ό λ°μμ΅λλ€.'
μ μ½λλ₯Ό 보면 μλ°μ€ν¬λ¦½νΈλ λκΈ°μ μΌλ‘ μλνλ μΈμ΄μΈλ° μ μΆλ ₯ μμκ° λ§μ§λ§μ μλ 'μμ μ΄ λλ¬μ΅λλ€!'κ° λ¨Όμ μΆλ ₯λμμκΉμ?
λ°λ‘ setTimeoutμ λΉλκΈ°μ μΌλ‘ μ€νλλ λΉλκΈ° ν¨μμ΄κΈ° λλ¬Έμ λλ€.
setTimeoutμ΄ λΉλκΈ°μ μΌλ‘ μ€νλ μ μλ μ΄μ λ λ°λ‘ setTimeoutμ WebApisμμ κ΄λ¦¬λκ³ λ©ν° μ€λ λ νκ²½μμ μ€νλκΈ° λλ¬Έμ λλ€. (μ΄μ κ΄λ ¨ν΄μλ Event Loopμ μ§μμ΄ νμν©λλ€.)
setTiemoutμ΄ λΉλκΈ°μ μΌλ‘ μ€νλκΈ° λλ¬Έμ setTimeoutμ μμ μ κΈ°λ€λ¦¬μ§ μκ³ λ€μ μ½λμΈ 'μμ μ΄ λλ¬μ΅λλ€'λΌλ κ²°κ³Όκ° λ¨Όμ μΆλ ₯λλ κ²μ λλ€.
κ·Έλ°λ°, μ΄ κ²°κ³Όλ μ°λ¦¬κ° λ°λΌλ κ²°κ³Όκ° μλλλ€.
'λ°μ΄ν°λ₯Ό λ°μμ΅λλ€.'λ₯Ό μΆλ ₯νκ³ κ·Έλ€μ μμλ‘ 'μμ μ΄ λλ¬μ΅λλ€!'λΌλ κ²°κ³Όλ₯Ό λ³΄λ €λ©΄ μ΄λ»κ² ν΄μΌ ν κΉμ?
μ΄λ΄ λ λΉλκΈ° μ½λ°±μ μ΄μ©ν΄μ μνλ κ²°κ³Όλ₯Ό μ»μ μ μμ΅λλ€.
function getData(callback) {
setTimeout(() => {
console.log('λ°μ΄ν°λ₯Ό λ°μμ΅λλ€.');
callback();
}, 3000);
}
getData(() => console.log('μμ
μ΄ λλ¬μ΅λλ€!'));
// μΆλ ₯ μμ
// 1. 'λ°μ΄ν°λ₯Ό λ°μμ΅λλ€.'
// 2. 'μμ
μ΄ λλ¬μ΅λλ€!'
μ μ½λμ κ°μ΄ getData ν¨μμ μΈμλ‘ μ½λ°±ν¨μλ₯Ό μ λ¬νμ΅λλ€.
κ·Έλμ μ½λμ μ€νμμλ₯Ό μ΄ν΄λ³΄λ©΄
- getData ν¨μμ 'μμ μ΄ λλ¬μ΅λλ€!'λ₯Ό μΆλ ₯νλ μ½λ°± ν¨μ μ λ¬ λ° μ€ν
- getData ν¨μμ setTimeout ν¨μ μ€ν
- 3μ΄κ° μ§λ λ€ setTimeoutμ μ½λ°± ν¨μμ μ½λλ₯Ό μμ°¨μ μΌλ‘ μ€ν
- 'λ°μ΄ν°λ₯Ό λ°μμ΅λλ€.' μΆλ ₯
- getData ν¨μμ μ λ¬λ μ½λ°± ν¨μκ° μ€νλμ΄ 'μμ μ΄ λλ¬μ΅λλ€!' μΆλ ₯
μ΄λ κ² μνλ μμ μ΄ μλ£λ μ΄νμ μ€νλλλ‘, μ¦ λΉλκΈ°μ μΌλ‘ λμνλ μ½λλ₯Ό λκΈ°μ μΌλ‘ μ²λ¦¬ν μ μκ² λμμ΅λλ€.
μ½λ°± ν¨μμ λ¬Έμ μ
νμ§λ§, μ¬λ¬ κ°μ μμ μ μ²λ¦¬νλ κ²½μ°μ λ¬Έμ κ° λ°μν©λλ€.
function firstTask(callback) {
setTimeout(() => {
console.log('첫λ²μ§Έ μμ
μλ£!');
callback();
}, 1500);
}
function secondTask(callback) {
setTimeout(() => {
console.log('λλ²μ§Έ μμ
μλ£!');
callback();
}, 1000);
}
function thirdTask() {
setTimeout(() => {
console.log('μΈλ²μ§Έ μμ
μλ£!');
}, 500);
}
firstTask(() => {
secondTask(() => {
thirdTask();
});
});
μ μ½λμ κ°μ΄ μ μ μ²λ¦¬ν λΆλΆμ΄ λ§μμ§λ€λ©΄ μλμ κ°μ μ½λλ‘ λ³νκ² λ©λλ€.
μμ κ°μ νμμ λ°λ‘ 'μ½λ°± μ§μ₯(Callback Hell)'μ΄λΌκ³ ννν©λλ€.
μ½λ°± μ§μ₯μ λΉλκΈ° μμ
μ΄ μλ‘ μ°κ²°λμ΄ μκ±°λ μμ°¨μ μΌλ‘ μ€νλμ΄μΌ ν λ, μ½λ°± ν¨μκ° μ€μ²©λμ΄ μ½λμ κΉμ΄κ° κΉμ΄μ§κ³ , μ΄λ‘ μΈν΄μ κ°λ
μ±μ΄ λ¨μ΄μ§λ©°, μ μ§λ³΄μκ° μ΄λ €μμ§λ νμμ
λλ€.
Promise
μμμ μ΄ν΄λ³Έ μ½λ°± μ§μ₯μ ν΄κ²°νκΈ° μν΄ ES6μμ PromiseλΌλ κ°λ μ΄ λ±μ₯νμ΅λλ€.
Promiseλ?
λΉλκΈ° μ²λ¦¬μ μ¬μ©λλ μλ°μ€ν¬λ¦½νΈ κ°μ²΄λ‘, λΉλκΈ° μμ μ μ΅μ’ μλ£(λλ μ€ν¨)μ κ·Έ κ²°κ³Ό κ°μ λνλ λλ€.
Promise κ°μ²΄λ 'μν(state)'μ 'κ°(result)'λΌλ λ κ°μ§ μμ±μ κ°μ§κ³ μμ΅λλ€.
μνμλ λκΈ°(pending), μ΄ν(fulfilled), κ±°λΆ(rejected)μ μΈ κ°μ§ μνκ° μμ΅λλ€.
- λκΈ°(pending): μμ§ μμ μ΄ μλ£λμ§λ μμκ³ , μ€ν¨νμ§λ μμ μ΄κΈ° μν
- μ΄ν(fulfilled): μμ μ΄ μ±κ³΅μ μΌλ‘ μλ£λ μν
- κ±°λΆ(rejected): μμ μ΄ μ€ν¨ν μν
μμ κ°μ΄ μμλ‘, μ±κ³΅ μνμΈ Promise κ°μ²΄λ₯Ό μΆλ ₯νλ©΄, μνλ 'fulfilled'κ° λκ³ , κ²°κ³Ό κ°μλ μ±κ³΅ μ λ°νκ°μ΄ λ΄κΉλλ€.
λκΈ° μνμμλ κ²°κ³Ό κ°μ 'undefined'κ° λ΄κΈ°λ©°, μ€ν¨ μνμλ μλ¬μ λ΄μ©μ΄ λ΄κΈ°κ² λ©λλ€.
Promise κ°μ²΄λ ν λ² μ±κ³΅νκ±°λ μ€ν¨νλ©΄ κ·Έ μνκ° κ³ μ λ©λλ€. μ΄λ‘ μΈν΄μ μμ μ μΌλ‘ λΉλκΈ° μ²λ¦¬λ₯Ό ν μ μμ΅λλ€.
λν, Promiseλ then(), catch(), finally() λ±μ λ©μλλ₯Ό μ 곡ν©λλ€.
- then(): Promiseκ° μ±κ³΅μ μΌλ‘ μ΄ν(μλ£)λ λ μ€νν μ½λλ₯Ό μμ±ν©λλ€.
- catch(): μμ μ΄ κ±°λΆ(μ€ν¨)νμ λ μ€νν μ½λλ₯Ό μμ±ν©λλ€.
- finally(): μμ μ μ±κ³΅, μ€ν¨ μ¬λΆμ κ΄κ³μμ΄ λ§μ§λ§μ 무쑰건 μ€νλμ΄μΌ νλ μ½λλ₯Ό μμ±ν©λλ€.
ν΄λΉ λ©μλλ€λ Promise κ°μ²΄λ₯Ό λ°νν©λλ€.
κ·Έλ¦¬κ³ Promise κ°μ²΄λ 'executor'λΌλ ν¨μλ₯Ό μΈμλ‘ λ°μ μμ±λ©λλ€.
μ΄ executor ν¨μλ new Promise κ°μ²΄κ° μμ±λμλ§μ μ€νλλ©°, λ κ°μ μ½λ°± ν¨μλ₯Ό μΈμλ‘ λ°μ΅λλ€.
- resolve: λΉλκΈ° μμ μ΄ μ±κ³΅μ μΌλ‘ μλ£λμμ λ νΈμΆλλ ν¨μ. μ΄ ν¨μλ₯Ό ν΅ν΄ Promiseλ μ±κ³΅(fulfilled) μνκ° λ¨.
- reject: λΉλκΈ° μμ μ λ¬Έμ κ° μκ²Όμ λ νΈμΆλλ ν¨μ. μ΄ ν¨μλ₯Ό ν΅ν΄ Promiseλ κ±°λΆ(rejected) μνκ° λ¨.
Promise μμ
μμ£Ό κΈ°λ³Έμ μΈ Promise μμ λ₯Ό 보면 μλ μ½λμ κ°μ΅λλ€.
const promise = new Promise((resolve, reject) => {
const success = true; // μ€μ λ‘λ μ΄λ€ λΉλκΈ° μμ
μ κ²°κ³Όμ λ°λΌ κ²°μ λ¨. μ€ν¨ λ° μ±κ³΅μ λν μμμΌ λΏμ
λλ€.
if (success) {
// λΉλκΈ° μμ
μ΄ μ±κ³΅ν κ²½μ°
resolve('μμ
μ΄ μ±κ³΅μ μΌλ‘ μλ£λμμ΅λλ€.');
} else {
// λΉλκΈ° μμ
μ΄ μ€ν¨ν κ²½μ°
reject('μμ
μ μ€ν¨νμμ΅λλ€.');
}
});
promise
.then((message) => {
// Promiseκ° μ±κ³΅λ κ²½μ° μ€νλ ν¨μ
console.log('μ±κ³΅ λ©μμ§: ' + message);
})
.catch((message) => {
// Promiseκ° κ±°λΆλ κ²½μ° μ€νλ ν¨μ
console.log('μ€ν¨ λ©μμ§: ' + message);
})
.finally(() => {
// μ±κ³΅, μ€ν¨ μ¬λΆμ μκ΄ μμ΄ λ§μ§λ§μ μ€ν
console.log('μμ
μ΄ λλ¬μ΅λλ€');
});
κ·ΈλΌ μ΄μ μ λΉλκΈ° μ½λ°±μ Pomiseλ‘ μ²λ¦¬νκ² λλ©΄ μ΄λ»κ² λ°λ μ μμκΉμ?
λ°λ‘ μλμ κ°μ΄ λ³ν μ μμ΅λλ€.
function firstTask() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('첫λ²μ§Έ μμ
μλ£!');
resolve();
}, 1500);
});
}
function secondTask() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('λλ²μ§Έ μμ
μλ£!');
resolve();
}, 1000);
});
}
function thirdTask() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('μΈλ²μ§Έ μμ
μλ£!');
resolve();
}, 500);
});
}
firstTask()
.then(() => secondTask())
.then(() => thirdTask())
.catch((error) => console.log(error));
μμ κ°μ΄. then λ©μλλ₯Ό μ°μμ μΌλ‘ νΈμΆνμ¬ μ¬λ¬ κ°μ Promiseλ₯Ό μ°κ²°νλ λ°©μμ Promise 체μΈμ΄λΌκ³ ν©λλ€.
Promise 체μΈμ ν΅ν΄μ λΉλκΈ° μμ μ κ²°κ³Όλ₯Ό μ΄μ΄λ°μ μ¬μ©νκ±°λ, μ¬λ¬ λΉλκΈ° μμ μ μμ°¨μ μΌλ‘ μ€ννμ¬, ꡬ쑰νλ μ½λλ₯Ό μμ±ν μ μμ΅λλ€.
μλ μ½λμ κ°μ΄ λ κΉλνκ² ννν μλ μμ΅λλ€.
firstTask()
.then(secondTask)
.then(thirdTask)
.catch(console.log);
νμ§λ§, μ΄λ° λ°©μμ 체μΈμ΄ κΈΈμ΄μ§μλ‘ κ²°κ΅ κ°λ μ±μ΄ λ¨μ΄μ§κ² λ©λλ€.
function firstTask() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('첫λ²μ§Έ μμ
μλ£!');
resolve('첫λ²μ§Έ μμ
κ²°κ³Ό');
}, 1500);
});
}
function secondTask(result) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('λλ²μ§Έ μμ
μλ£!');
resolve(result + ' -> λλ²μ§Έ μμ
κ²°κ³Ό');
}, 1000);
});
}
function thirdTask(result) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('μΈλ²μ§Έ μμ
μλ£!');
resolve(result + ' -> μΈλ²μ§Έ μμ
κ²°κ³Ό');
}, 500);
});
}
function fourthTask(result) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('λ€λ²μ§Έ μμ
μλ£!');
resolve(result + ' -> λ€λ²μ§Έ μμ
κ²°κ³Ό');
}, 200);
});
}
firstTask()
.then((result) => {
// μΆκ°μ μΈ μμ
μ μννκ³ κ·Έ κ²°κ³Όλ₯Ό λ€μ Promiseλ‘ μ λ¬
const processedResult = result + ' -> μ€κ° μ²λ¦¬';
console.log(`첫λ²μ§Έ μμ
ν μ²λ¦¬: ${processedResult}`);
return secondTask(processedResult);
})
.then((result) => {
// μΆκ°μ μΈ μμ
μ μννκ³ κ·Έ κ²°κ³Όλ₯Ό λ€μ Promiseλ‘ μ λ¬
const processedResult = result + ' -> μ€κ° μ²λ¦¬';
console.log(`λλ²μ§Έ μμ
ν μ²λ¦¬: ${processedResult}`);
return thirdTask(processedResult);
})
.then((result) => {
// μΆκ°μ μΈ μμ
μ μννκ³ κ·Έ κ²°κ³Όλ₯Ό λ€μ Promiseλ‘ μ λ¬
const processedResult = result + ' -> μ€κ° μ²λ¦¬';
console.log(`μΈλ²μ§Έ μμ
ν μ²λ¦¬: ${processedResult}`);
return fourthTask(processedResult);
})
.then((finalResult) => console.log(`μ΅μ’
κ²°κ³Ό: ${finalResult}`))
.catch((error) => console.log(error));
Promiseλ μ½λ°± μ§μ₯ λ¬Έμ λ₯Ό ν΄κ²°νκΈ° μν΄ λμ λμμΌλ, λ©μλ 체μ΄λμ ν΅ν μ°μμ μΈ λΉλκΈ° μμ μ²λ¦¬λ κ°λ μ±μ μ¬μ ν λ¨μ΄λ¨λ¦΄ μ μμ΅λλ€.
νμ§λ§ μ΄λ° λ¨μ μ κ°μνλλΌλ, Promiseλ κ·Έ μμ²΄λ‘ ν° κ°μΉλ₯Ό κ°μ§κ³ μμ΅λλ€.
λλ¦μ νμ€μ μ ν΄λκ³ κ²°κ³Όλ₯Ό μμΈ‘νκΈ° μ½κ² λ§λ€μ΄μ£Όλ©°, μ½λμ μ λ’°μ±μ λμ΄λ λ° ν¬κ² κΈ°μ¬νκΈ° λλ¬Έμ λλ€.
μ λλ μ΄ν°(Generator)
μ λλ μ΄ν° λν ES6μ λμ λ κ°λ μ λλ€.
μ λλ μ΄ν°λ?
μ λλ μ΄ν°λ μ½λ λΈλ‘μ μ€νμ μΌμ μ€μ§ νλ€κ° νμν μμ μ μ¬κ°ν μ μλ νΉμν ν¨μμ λλ€.
μΌλ° ν¨μμλ λ€λ₯΄κ², μ λλ μ΄ν° ν¨μλ₯Ό νΈμΆνλ©΄ λ°λ‘ ν¨μμ λ΄μ©μ΄ μ€νλμ§ μκ³ , μ λλ μ΄ν° κ°μ²΄κ° λ°νλ©λλ€.
μ λλ μ΄ν° κ°μ²΄λ μ΄ν°λ¬λΈ(iterable)μ΄λ©΄μ λμμ μ΄ν°λ μ΄ν°(iterator)μ λλ€.
- μ΄ν°λ¬λΈ(iteralble): λ°λ³΅ κ°λ₯ν μλ£κ΅¬μ‘°λ₯Ό μλ―Έν©λλ€. μ¬κΈ°μ λ°λ³΅ κ°λ₯νλ€λ κ²μ κ° μμλ₯Ό ν λ²μ νλμ© μ²λ¦¬ν μ μλ€λ λ»μ λλ€. μ΄ν°λ¬λΈ κ°μ²΄λ [Symbol.iterator] λ©μλλ₯Ό ꡬνν΄μΌ ν©λλ€. μ΄ λ©μλλ₯Ό νΈμΆνλ©΄ μ΄ν°λ μ΄ν°λ₯Ό λ°ννκ³ , λ°°μ΄, λ¬Έμμ΄, Map, Set λ±μ΄ μ΄ν°λ¬λΈμ ν΄λΉλ©λλ€. μ΄ν°λ¬λΈμ μ¬μ©νλ©΄ for...of λ°λ³΅λ¬Έ, μ€νλ λ μ°μ°μ(...), ꡬ쑰 λΆν΄ ν λΉ λ±μμ μ¬μ©ν μ μμ΅λλ€.
- μ΄ν°λ μ΄ν°(iterator): 'λ€μ' μμλ₯Ό λ°ννλ next() λ©μλλ₯Ό κ°μ§ κ°μ²΄λ₯Ό μλ―Έν©λλ€. next() λ©μλλ {value, done} ννμ κ°μ²΄λ₯Ό λ°ννλ©°, valueλ λ€μ κ°μ΄κ³ , doneμ μ λλ μ΄ν° ν¨μκ° λͺ¨λ μ€νλμ΄ μ’ λ£λμλμ§μ μ¬λΆμ λλ€.
μ λλ μ΄ν° μ¬μ© λ°©λ²
- function* ν€μλλ‘ μ μΈλ©λλ€.
- yield ν€μλλ₯Ό μ¬μ©νμ¬ ν¨μμ μ€νμ μ€λ¨νκ³ μ¬κ°ν μ μμ΅λλ€.
- next λ©μλλ₯Ό νΈμΆνλ©΄ μ λλ μ΄ν°κ° μ²μλΆν° μ€νλκ±°λ, μ΄μ μ yield ν€μλμμ λ©μ·λ λΆλΆλΆν° μ€νλ©λλ€.
- next λ©μλμ μΈμλ₯Ό μ λ¬νλ©΄, κ·Έ κ°μ μ λλ μ΄ν° ν¨μ λ΄λΆμμ yield ν€μλμ κ²°κ³Όκ°μΌλ‘ μ¬μ©λ©λλ€.
- yield ν€μλλ μ λλ μ΄ν° ν¨μμ μ€νμ λ©μΆκ³ , μ€ν κΆνμ νΈμΆμμκ² μλν©λλ€.
- μ΄νμ next λ©μλκ° νΈμΆλλ©΄ μ€ν κΆνμ΄ λ€μ μ λλ μ΄ν° ν¨μμκ² μ΄λν©λλ€.
- ν¨μλ yield ν€μλ μ΄νμ λΆλΆλΆν° μ€νμ μ΄μ΄κ°λλ€.
function* generatorFunction() {
console.log('ν¨μ μμ');
const x = yield 1;
console.log('첫 λ²μ§Έ yield μ΄ν ' + x);
yield 2;
console.log('λ λ²μ§Έ yield μ΄ν');
return 3; // μ λλ μ΄ν° ν¨μκ° μ’
λ£λλ©΄μ λ°ννλ κ°
}
const generator = generatorFunction();
const one = generator.next(); // 'ν¨μ μμ'
console.log(one); // {value: 1, done: false}
const two = generator.next(99); // '첫 λ²μ§Έ yield μ΄ν 99'
console.log(two); // {value: 2, done: false}
const three = generator.next(); // 'λ λ²μ§Έ yield μ΄ν'
console.log(three); // {value: 3, done: true}
μ΄λ κ² μ λλ μ΄ν°λ₯Ό μ¬μ©νλ©΄ ν¨μμ μ€νμ μΈλ°νκ² μ μ΄ν μ μμ΅λλ€.
μ¦, λΉλκΈ° μμ μ λκΈ°μ μΈ λ°©μμΌλ‘ μμ±ν μ μκ² ν΄ μ€λλ€.
async/await
async/awaitμ ES8μ λμ λμμ΅λλ€.
νλ‘λ―Έμ€(Promise)λ₯Ό κΈ°λ°μΌλ‘ νλ©°, μ΄μ λ³΄λ€ λμ± λΉλκΈ° μ²λ¦¬λ₯Ό μ½κ² ν μ μκ² λμμ΅λλ€.
async/awaitμ κΈ°μ‘΄μ λΉλκΈ° μ²λ¦¬λ₯Ό μν΄ μ¬μ©λλ νλ‘λ―Έμ€(Promise)μ μ λλ μ΄ν°(Generator)μ λ¬Έμ μ μ ν΄κ²°νκΈ° μν΄ λ±μ₯νμ΅λλ€.
μ΄μ μ λ΄μ©μ λν΄ λ¬Έμ μ μ κ°λ¨ν μ 리νμλ©΄ μλμ κ°μ΅λλ€.
Promiseμ λ¬Έμ μ
- 체μ΄λ: νλ‘λ―Έμ€κ° μ°μμ μΌλ‘ μ΄μ΄μ§λ κ²½μ°, μ½λκ° λ³΅μ‘νκ³ κ°λ μ±μ΄ λ¨μ΄μ§λ€.
- μμΈ μ²λ¦¬: μμΈλ₯Ό μ μ ν μ²λ¦¬νκΈ° μν΄μλ κ° νλ‘λ―Έμ€λ§λ€ μλ¬ νΈλ€λ¬λ₯΄ λΆμ΄μ£Όμ΄μΌ νλ€. μ΄λ‘ μΈν΄ μ½λλ₯Ό 볡μ‘νκ² λ§λ λ€.
μ λλ μ΄ν°μ λ¬Έμ μ
- μ΄ν΄νκΈ° μ΄λ ΅λ€: μ΄ν°λ¬λΈκ³Ό μ΄ν°λ μ΄ν°μ κ°λ μ μ΄ν΄ν΄μΌ νλ©°, μ΄ μ체λ‘λ μ¬μ΄ λ΄μ©μ μλλ€.
- μ§μ μ μ΄: ν¨μμ μ€νμ μ μ΄νκΈ° μν΄μλ μ λλ μ΄ν° κ°μ±μ next λ©μλλ₯Ό μ§μ νΈμΆν΄μΌ νλ€.
μ¦, async/awaitμ μμ κ°μ λ¬Έμ μ λ€μ ν΄κ²°νκ³ μ λμ λμμ΅λλ€.
νλ‘λ―Έμ€λ₯Ό κΈ°λ°μΌλ‘ νλ©°, μ λλ μ΄ν°μ μ μ¬ν λμ λ°©μμ κ°κ³ μμ΅λλ€.
async ν¨μ
asyncλ λΉλκΈ° ν¨μλ₯Ό μ μν λμ¬μ©λ©λλ€.
νμ Promiseλ₯Ό λ°ννλ©°, λ§μ½ λ°ν κ°μ΄ νλ‘λ―Έμ€κ° μλλΌλ©΄, Promise.resolve λ©μλμ μν΄μ μλμΌλ‘ Promiseλ₯Ό κ°μΈμ λ°νν©λλ€.
await ν€μλ
await ν€μλλ async ν¨μ λ΄λΆμμλ§ μ¬μ©μ΄ κ°λ₯ν©λλ€.
λΉλκΈ° μμ μ λ§μΉ λκΈ°μ μΌλ‘ μννλ κ²μ²λΌ ν μ μμΌλ©°, await ν€μλλ ν¨μμ μ§νμ λ©μΆ₯λλ€.
μ¦, νλ‘λ―Έμ€μ μλ£λ₯Ό κΈ°λ€λ¦¬κ² λ©λλ€.
async function asyncFunction() {
const value1 = await doSomethingAsync();
const value2 = await doSomethingElseAsync(value1);
const value3 = await doAnotherAsyncThing(value2);
return doSomethingWith(value3);
}
μ£Όμν μ β
νλ‘λ―Έμ€λ₯Ό λ°ννμ§ μλ μ°μ°μ awaitλ₯Ό μ¬μ©νλ©΄, κ·Έ μ°μ°μ μ¦μ ν΄κ²°λ Promiseλ‘ κ°μ£Όλμ΄ await ν€μλκ° λ³λμ ν¨κ³Όλ₯Ό κ°μ§ μκ² λ©λλ€.
μ¬μ© μμ
async function runTasks() {
try {
const firstResult = await firstTask();
console.log('첫λ²μ§Έ μμ
κ²°κ³Ό:', firstResult);
const secondResult = await secondTask(firstResult);
console.log('λλ²μ§Έ μμ
κ²°κ³Ό:', secondResult);
const thirdResult = await thirdTask(secondResult);
console.log('μΈλ²μ§Έ μμ
κ²°κ³Ό:', thirdResult);
const fourthResult = await fourthTask(thirdResult);
console.log('λ€λ²μ§Έ μμ
κ²°κ³Ό:', fourthResult);
} catch (error) {
console.error('μμ
μ€ μλ¬ λ°μ:', error);
}
}
runTasks();
κ°κ°μ μμ μ await ν€μλλ₯Ό μ¬μ©νμ¬ νλ‘λ―Έμ€κ° μ΄νλ λκΉμ§ κΈ°λ€λ¦½λλ€.
λ§μ½ νλ‘λ―Έμ€κ° κ±°λΆλλ©΄, catch λΈλ‘μμ μλ¬λ₯Ό μ²λ¦¬ν μ μμ΅λλ€.
μ΄λ κ² async/awaitμ μ¬μ©νλ©΄ λΉλκΈ° μμ μ νλ¦μ λκΈ°μ μΈ λ°©μμΌλ‘ μ½κ² ννν μ μμ΅λλ€.
λ§λ¬΄λ¦¬ π
μ½λ°±ν¨μλΆν° async/awaitκΉμ§ κΈ°μ‘΄μ λΉλκΈ° μ²λ¦¬μ μμ΄μ μ΄λ€ λΆνΈν¨μ΄ μμκ³ μ΄λ»κ² κ°μ λμλμ§μ λν΄ μμ보λ μκ°μ΄μμ΅λλ€.
μ°Έκ³ λ¬Έν:
- https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Generator
- https://seo-tory.tistory.com/77
- https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise
- https://youtu.be/mYHVOTxEwlY?si=KBZGmUCif3RJE1eM
- https://www.youtube.com/watch?v=6-8mbuUC3fk
- https://www.youtube.com/watch?v=qi24UqyJLgs
- https://www.youtube.com/watch?v=ZrdHtL1gcEI