์ฝ๋ฐฑ์ง์ฅ(callback hell)์ด๋, ์ฝ๋ฐฑํจ์๋ฅผ ์ต๋ช
ํจ์๋ก ์ ๋ฌํ๋ ๊ณผ์ ์ด ๋ฐ๋ณต๋์ด ์ฝ๋์ ๋ค์ฌ์ฐ๊ธฐ ์์ค์ด ๊ฐ๋นํ๊ธฐ ํ๋ค ์ ๋๋ก ๊น์ด์ง๋ ํ์์
๋๋ค.
์ฆ, ์ฝ๋ฐฑํจ์์ ๋ ์ฝ๋ฐฑํจ์๋ฅผ ์ ๋ฌํ๊ณ , ๊ทธ ์ฝ๋ฐฑํจ์์ ๋ ์ฝ๋ฐฑํจ์๋ฅผ ์ ๋ฌํ๋ ๊ณผ์ ์ด ๋ฐ๋ณต๋ ํํ์
๋๋ค.
์ฃผ๋ก ๋น๋๊ธฐ ์์
์ ์ํํ๊ธฐ ์ํด ์ด๋ฐ ํํ๊ฐ ์์ฃผ ๋ฑ์ฅํฉ๋๋ค.
Promise๋ ๋น๋๊ธฐ์ ์ธ ๊ฒ์ ์ํํ ๋ ์ฝ๋ฐฑํจ์ ๋์ ์ ์ ์ฉํ๊ฒ ์ฐ์ผ ์ ์๋ ์ค๋ธ์ ํธ์ ๋๋ค.
const promise = new Promise((resolve, reject) => {
console.log('doing something...');
setTimeout(() =>
resolve('์ฑ๊ณต')
//reject('์คํจ')
, 200);
})
//Promise๋ฅผ ๋ง๋๋ ์๊ฐ ์ ๋ฌํ ์ฝ๋ฐฑํจ์๊ฐ ์ฆ์ ์คํ๋ฉ๋๋ค.
//์ด ์ฝ๋ฐฑํจ์๋ resolve, reject๋ผ๋ ์ฝ๋ฐฑ์ ์ ๋ฌ๋ฐ์ต๋๋ค.
//๋น๋๊ธฐ์์
์ด ์ฑ๊ณตํ ๊ฒฝ์ฐ resolve(...)๋ฅผ, ์คํจํ ๊ฒฝ์ฐ reject(...) ํธ์ถ
promise
.then(console.log) //resolve()๊ฐ ๋ฐํ๋ ๊ฒฝ์ฐ ์คํ
.catch(console.log) //reject()๊ฐ ๋ฐํ๋ ๊ฒฝ์ฐ ์คํ
.finally(console.log('finally'));
//finally() ๋ฉ์๋๋ Promise๊ฐ resolve ํน์ reject๊ฐ ๋ฐํ๋์๋์ง์ ๊ด๊ณ์์ด ์ง์ ๋ ์ฝ๋ฐฑํจ์๊ฐ ์คํ๋ฉ๋๋ค. ๋ฐ๋ผ์ ์ด๋ ํ ์ธ์๋ ์ ๋ฌ๋ฐ์ง ์์ต๋๋ค.
๋น๋๊ธฐ ์์
์ ๋๊ธฐ์ ํํ(1) - Promise
new Promise(resolve =>
setTimeout(() => {
const name = '์์คํ๋ ์';
console.log(name);
resolve(name);
}, 500)
).then(prevName => new Promise(resolve =>
setTimeout(() => {
const name = prevName + ', ์๋ฉ๋ฆฌ์นด๋
ธ';
console.log(name);
resolve(name);
}, 500))
).then(prevName => new Promise(resolve =>
setTimeout(() => {
const name = prevName + ', ์นดํ๋ชจ์นด';
console.log(name);
resolve(name);
}, 500))
).then(prevName => new Promise(resolve =>
setTimeout(() => {
const name = prevName + ', ์นดํ๋ผ๋ผ';
console.log(name);
}, 500))
);
//์์คํ๋ ์
//์์คํ๋ ์, ์๋ฉ๋ฆฌ์นด๋
ธ
//์์คํ๋ ์, ์๋ฉ๋ฆฌ์นด๋
ธ, ์นดํ๋ชจ์นด
//์์คํ๋ ์, ์๋ฉ๋ฆฌ์นด๋
ธ, ์นดํ๋ชจ์นด, ์นดํ๋ผ๋ผ
//(0.5์ด๋ง๋ค ์์๋๋ก ์ถ๋ ฅ)
์์ ๋น๋๊ธฐ์ฝ๋๋ฅผ ๊ธฐ๋ช ํจ์๋ก ๋ณํํ๋ฉด, ์คํ์ ๋ ๊ฐ๋จํ๊ฒ ํํํ ์ ์์ต๋๋ค.
const addEspresso = ()=> new Promise(resolve => {
setTimeout(() => {
const name = '์์คํ๋ ์'
console.log(name);
resolve(name);
}, 500)
});
const addAmericano = (prevName) => new Promise(resolve => {
setTimeout(() => {
const name = prevName + ', ์๋ฉ๋ฆฌ์นด๋
ธ';
console.log(name);
resolve(name);
}, 500)
});
const addCafeMocha = (prevName) => new Promise(resolve => {
setTimeout(() => {
const name = prevName + ', ์นดํ๋ชจ์นด';
console.log(name);
resolve(name);
}, 500)
});
const addCafeLatte = (prevName) => new Promise(resolve => {
setTimeout(() => {
const name = prevName + ', ์นดํ๋ผ๋ผ';
console.log(name);
resolve(name);
}, 500)
});
addEspresso()
.then(prevName => addAmericano(prevName))
.then(prevName => addCafeMocha(prevName))
.then(prevName => addCafeLatte(prevName));
//์ฝ๋ฐฑํจ์๋ฅผ ์ ๋ฌํ ๋ ๋ฐ์์ค๋ ๊ฐ์ผ๋ก ๋ฐ๋ก ๋ค์ ํจ์๋ฅผ ํธ์ถํ๋ ๊ฒฝ์ฐ์๋ ๋ ๊ฐ๋จํ๊ฒ ํํํ ์ ์์ต๋๋ค.
addEspresso()
.then(addAmericano)
.then(addCafeMocha)
.then(addCafeLatte);
๋ฐ๋ณต์ ์ธ ํจ์ ์ ์ธ์ ์งง๊ฒ ํํํ๋ฉด,
const addCoffee = function(name) {
return function(prevName) {
return new Promise(resolve => {
setTimeout(() => {
var newName = prevName ? (prevName + ', ' + name) : name;
console.log(newName);
resolve(newName);
}, 500);
});
};
};
addCoffee('์์คํ๋ ์')()
.then(addCoffee('์๋ฉ๋ฆฌ์นด๋
ธ'))
.then(addCoffee('์นดํ๋ชจ์นด'))
.then(addCoffee('์นดํ๋ผ๋ผ'));
function ๋ค์ *๊ฐ ๋ถ์ ํจ์๋ generatorํจ์ ์
๋๋ค. generator ํจ์๋ฅผ ์คํํ๋ฉด Iterator๊ฐ ๋ฐํ๋๋๋ฐ, ์ด Iterator๋ next๋ฉ์๋๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค.
next ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด generatorํจ์ ๋ด๋ถ์์ ๊ฐ์ฅ ๋จผ์ ๋ฑ์ฅํ๋ yield์์ ์คํ์ ๋ฉ์ถ๊ณ , ์ดํ ๋ค์ next๋ฉ์๋๋ฅผ ํธ์ถ ํ๋ฉด ์์ ๋ฉ์ท๋ ๋ถ๋ถ์์ ์์ํด์ ๊ทธ ๋ค์์ ๋ฑ์ฅํ๋ yield์์ ์คํ์ ๋ฉ์ถฅ๋๋ค. ๊ทธ๋ฌ๋๊น ๋น๋๊ธฐ ์์
์ด ์๋ฃ๋๋ ์์ ๋ง๋ค next๋ฉ์๋๋ฅผ ํธ์ถํด์ค๋ค๋ฉด generatorํจ์ ๋ด๋ถ์ ์์ค๊ฐ ์์์๋ถํฐ ์๋๋ก ์์ฐจ์ ์ผ๋ก ์งํ๋ฉ๋๋ค.
๋น๋๊ธฐ ์์
์ ๋๊ธฐ์ ํํ(2) - Generator
const addCoffee = function (prevName, name) {
setTimeout(function() {
coffeeMaker.next(prevName ? prevName + ', ' + name : name);
}, 500);
};
const coffeeGenerator = function* () {
const espresso = yield addCoffee('', '์์คํ๋ ์');
console.log(espresso);
const americano = yield addCoffee(espresso, '์๋ฉ๋ฆฌ์นด๋
ธ');
console.log(americano);
const mocha = yield addCoffee(americano, '์นดํ๋ชจ์นด');
console.log(mocha);
const latte = yield addCoffee(mocha, '์นดํ๋ผ๋ผ');
console.log(latte);
};
const coffeeMaker = coffeeGenerator();
coffeeMaker.next();
//0.5์ด๋ง๋ค next๋ฉ์๋๋ฅผ ํธ์ถ
๋น๋๊ธฐ ์์ ์ ์ํํ๊ณ ์ ํ๋ ํจ์ ์์ async๋ฅผ ๋ถ์ด๊ณ , await์ async๊ฐ ๋ถ์ ํจ์ ์์์๋ง ์ธ์ ์์ต๋๋ค. ์ค์ง์ ์ธ ๋น๋๊ธฐ ์์ ์ด ํ์ํ ์์น๋ง๋ค await๋ฅผ ํ๊ธฐํ๋ฉด ๋ค์ ๋ด์ฉ์ ์๋์ผ๋ก Promise๋ก ์ ํํ๊ณ , ํด๋น ๋ด์ฉ์ด resolve๋ ์ดํ์์ผ ๋ค์์ผ๋ก ์งํํฉ๋๋ค.
function fetchData() {
return new Promise((resolve, reject) => {
//do network request.....
resolve('์ฑ๊ณต');
});
}
async function fetchData2() {
//do network request...
return '์ฑ๊ณต';
}
fetchData().then(console.log); //์ฑ๊ณต
fetchData2().then(console.log); //์ฑ๊ณต
๋น๋๊ธฐ ์์
์ ๋๊ธฐ์ ํํ(3) - Promise + Async/await
const addCoffee = name =>
new Promise(resolve =>
setTimeout(() => resolve(name), 500)
);
const coffeeMaker = async() => {
let coffeeList = '';
const _addCoffee = async name => {
coffeeList += (coffeeList ? ',' : '') + await addCoffee(name);
};
await _addCoffee('์์คํ๋ ์');
console.log(coffeeList);
await _addCoffee('์๋ฉ๋ฆฌ์นด๋
ธ');
console.log(coffeeList);
await _addCoffee('์นดํ๋ชจ์นด');
console.log(coffeeList);
await _addCoffee('์นดํ๋ผ๋ผ');
console.log(coffeeList);
};
coffeeMaker();