๋๊ธฐ๋ฐฉ์ vs ๋น๋๊ธฐ๋ฐฉ์, ์ฝ๋ฐฑํจ์์ Promise ๊น์ง ํ๋ฒ์ ํ์ด๋ณด๊ธฐ!
๋ฐ์ดํฐ ์ฒ๋ฆฌ ๋ชจ๋ธ์ ๋ฐฉ์ :: ๋๊ธฐ๋ฐฉ์ vs ๋น๋๊ธฐ๋ฐฉ์
๋๊ธฐ๋ฐฉ์
์์ฐจ์ ์ผ๋ก ๋์ํ๋ ๋ฐฉ์
์์ฒญ์ ๋ณด๋ธ ํ ํด๋น ์๋ต์ ๋ฐ์์ผ ๋ค์ ๋์์ ์คํํ๋ฉฐ ์ด ๋์์ด ๋๋ ๋๊น์ง ๋ค์ ๋์์ ๋๊ธฐ์ํ์ด๋ค.
์ ๊ทธ๋ผ a์ฒ๋ผ ์นดํ์์ ์ค์ ์์ ์ปคํผ๋ฅผ ๋ฐ๋ ๋ฐฉ์์ผ๋ก ๋น์ ํ๋๋ฐ,
ํ ๋์์ด ๋๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ๊ธฐ ๋๋ฌธ์ ๋์์ด ๋๋ฆฌ๋ค๋ ๋๋์ ๋ฐ์ ์ ์๋ค.
์ด๊ฒ์ ์ค์ CPU๊ฐ ๋๋ ค์ง๋ ๊ฒ์ ์๋์ง๋ง ์์คํ ์ ์ฒด์ ์ธ ํจ์จ์ด ์ ํ๋๋ค๊ณ ๋ณผ ์ ์๋ค.
์ค๊ณ๊ฐ ๊ฐ๋จํ๊ณ ์ง๊ด์ ์ด๋ผ๋ ์ฅ์ ์ ๊ฐ์ง์ง๋ง, ๊ฒฐ๊ณผ๋ฅผ ๋ณผ ๋๊น์ง ์๋ฌด๊ฒ๋ ๋ชปํ๊ณ ๋๊ธฐํด์ผ ํ๋ค๋ ๋จ์ ์ด ์๋ค!
function func1(){
console.log("1๋ฒ์
๋๋ค");
func2();
}
function func2(){
console.log("2๋ฒ์
๋๋ค");
func3();
}
function func3(){
console.log("3๋ฒ์
๋๋ค");
}
func1();
//1๋ฒ์
๋๋ค
//2๋ฒ์
๋๋ค
//3๋ฒ์
๋๋ค
๋น๋๊ธฐ๋ฐฉ์
์์ฐจ์ ์ผ๋ก ์งํํ์ง ์๋ ๋ฐฉ์
์์ฒญ์ ๋ณด๋ด๊ณ ์๋ต์ ๊ด๊ณ์์ด ๋ฐ๋ก ๋ค์ ๋์์ ์คํํ๋ค.
๋๊ธฐ๋ณด๋ค ๋ณต์กํ์ง๋ง ๊ฒฐ๊ณผ๊ฐ ์ฃผ์ด์ง๋๋ฐ ์๊ฐ์ด ๊ฑธ๋ฆฌ๋๋ผ๋ ๊ทธ ์๊ฐ ๋์ ๋ค๋ฅธ ์์ ์ ํ ์ ์์ผ๋ฏ๋ก ์์์ ํจ์จ์ ์ผ๋ก ์ฌ์ฉํ ์ ์๋ ์ฅ์ ์ด ์๋ค.
why need?
ํด๋ผ์ด์ธํธ์์ ์๋ฒ๋ก ๋ฐ์ดํฐ๋ฅผ ์์ฒญ ํ์ ๋, ์๋ฒ๊ฐ ๊ทธ ์์ฒญ์ ๋ํ ์๋ต์ ์ธ์ ์ค์ง๋ ๋ชจ๋ฅด๋๋ฐ ๋ฐ์ดํฐ๊ฐ ๋ค ๋ฐ์์ง๋๊น์ง ์ฑ์ด ๋๊ธฐ์ํ๋ก ๋จธ๋ฌผ๋ฌ์์ ์ ์๊ธฐ ๋๋ฌธ์ ๋น๋๊ธฐ๋ฐฉ์์ด ํ์ํ๋ค.
* ์๋ฐ์คํฌ๋ฆฝํธ์์ ๋น๋๊ธฐ๋ฐฉ์์ด ๊ฐ๋ฅํ ์ด์
์๋ฐ์คํฌ๋ฆฝํธ๋ ํํ ์๊ณ ์๋ฏ ์ฑ๊ธ์ค๋ ๋๋ก ํ๋ก๊ทธ๋จ์ด ๋์ํ๋ค.
**์ฑ๊ธ์ค๋ ๋**
ํ ๋ฒ์ ํ๊ฐ์ง ์ผ๋ง ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅํ ๋จ์ผ ์ค๋ ๋
๊ทธ๋ฐ๋ฐ ๋์์ ์ฌ๋ฌ ์์ ์ด ๋์๋๋ ๋น๋๊ธฐ๋ฐฉ์์ ๋ฉํฐํ์คํน ์์ ์ผ ์ ๋ฐ์ ์๋๋ฐ ์ด๋ป๊ฒ ์๋ฐ์คํฌ๋ฆฝํธ์์ ๋น๋๊ธฐ๋ฐฉ์์ด ๊ฐ๋ฅํ๊ฑธ๊น?
์๋ฐ์คํฌ๋ฆฝํธ๋ ์น ๋ธ๋ผ์ฐ์ ๋ Node.js์ ์๋ฐ์คํฌ๋ฆฝํธ ์์ง์์ ์คํ์ด ๋๋ค.
์ด ์์ง์๋ ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ๋๋ฆฌ๋ ํ๋์ ์ค๋ ๋๊ฐ ์กด์ฌํ๋ค.
๋ํ ์ด ์์ง ๋ฟ๋ง ์๋๋ผ ์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ Web API๋ฅผ ๋์๊ณ , ๋น๋๊ธฐ์ ์ฒ๋ฆฌ ๋ชจ๋ธ์ธ Web API๋ผ๋ ๊ฒ์ด ํจ๊ป ๋์ํ๋ฉด์ ์ฌ๊ธฐ์์ setTimeout์ด๋ Ajax๋ฑ ๊ธฐ๋ค๋ฆฌ๋ ์๊ฐ์ด ํ์ํ ์ผ๋ค์ ์ฒ๋ฆฌํ๋ค.
์ด Web API๋ค์ด ์๋ฐ์คํฌ๋ฆฝํธ ์์ง ์ค๋ ๋์๋ ๋ฐ๋ก ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ๋ฐ๋ก ๋๋ฉด์ ์ฝ๋ฐฑํจ์๋ฅผ ๊ฐ์ง๊ณ ์ด๋ฒคํธ ๋ฃจํ์ ๋ค์ด๊ฐ ์ฒ๋ฆฌ๋๋๋๋ก ์ฝ๋ฐฑํจ์๋ฅผ ๋ค์ ์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ผ๋ก ๋๋ ค๋ณด๋ด์ค๋ค.
example
setTimeout, ajax ...
setTimeout
function func1(){
console.log("1๋ฒ์
๋๋ค");
func2();
}
function func2(){
setTimeout(
console.log("2๋ฒ์
๋๋ค");
, 3000
);
func3();
}
function func3(){
console.log("3๋ฒ์
๋๋ค");
}
func1();
//1๋ฒ์
๋๋ค
//3๋ฒ์
๋๋ค
//2๋ฒ์
๋๋ค
ajax
function getData() {
var tableData;
$.get('url', function (response) {
tableData = response;
}) // $.get()๋ก ๋ฐ์ดํฐ๋ฅผ ์์ฒญํ๊ณ ๋ฐ์์ฌ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ return ํด๋ฒ๋ฆผ
return tableData;
}
console.log(tableData) // ๋ฐ๋ผ์ undefined
์ด๋, ๋น๋๊ธฐ๋ฐฉ์์ ๋ฌธ์ ์ ์ ํ์ธํ ์ ์๋ค.
๋น๋๊ธฐ๋ฐฉ์์ ๋ฌธ์ ์
๋ฐ๋ก ๋ฐ์ดํฐํต์ ์ด ๋๊ธฐ๋ ์ ์ ๊ฐ์ returnํด๋ฒ๋ฆฌ๊ฒ ๋๊ฑฐ๋ ์ด ๊ฐ์ ์ด์ฉํ๋ ์ด๋ ํ ๋์์ด ๋์์ ์ด๋ฃจ์ด์ง ๊ฒฝ์ฐ undefined๊ฐ์ ์ฌ์ฉํ ์ ๋ฐ์ ์๋ค.
How can I do?
์ฝ๋ฐฑํจ์๋ฅผ ์ด์ฉํ์!
์ฝ๋ฐฑํจ์
์ฝ๋ฐฑํจ์๋?
- ๋ค๋ฅธ ํจ์์ ์ธ์๋ก์ ์ด์ฉ๋๋ ํจ์
- ์ด๋ค ์ด๋ฒคํธ์ ์ํด ํธ์ถ๋๋ ํจ์
callback์ ์ฝ๊ฒ ๋งํ์๋ฉด ์ด๋ค ์ผ์ ๋ค๋ฅธ ๊ฐ์ฒด์๊ฒ ์ํค๊ณ , ๊ทธ ์ผ์ด ๋๋๋ ๊ฒ์ ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ๋๋๊ณ ๋ถ๋ฅผ ๋๊น์ง ๋ค๋ฅธ ์ผ์ ํ๋ ๊ฒ์ ๋งํ๋ค.
function plus(x, y, callback) {
sum = x + y;
callback(sum)
}
function print(result) {
console.log(result);
}
plus( 1, 2, print);
๋์์์
- plusํจ์๊ฐ ์คํ๋๋ค.
- plusํจ์์ ๋งค๊ฐ๋ณ์์ธ 1๊ณผ 2์ ์ฐ์ฐ๊ฐ์ด sum์ผ๋ก ๋ค์ด๊ฐ๋ค.
- ๋งค๊ฐ๋ณ์์ธ callback์ ๋ค์ด๊ฐ ์ฝ๋ฐฑํจ์์ธ print๊ฐ callback์ ๋ค์ด๊ฐ๋ค.
- printํจ์๊ฐ ์คํ๋๋ค.
- printํจ์์ ์ธ์๋ก ์ฌ์ฉ๋ sum์ด console.log์ ๋ค์ด๊ฐ
- ์ฝ์์ 3์ด ๋์ด.
function increase(number, callback){
setTimeout(()=>{
const result=number+10;
if(callback){
callback(result);
}
},1000)
}
increase(0, result=>{
console.log(result);
});
์ฝ๋ฐฑํจ์ ์ค์ฒฉ
1์ด ๋ค result์ 10์ ๋ํด์ ๋ฐํํ๋ ํจ์๋ฅผ ์๋ก ๋ค์ด๋ณผ๋ 1์ด์ ๊ฑธ์ณ์ 10, 20, 30, 40 ๊ณผ ๊ฐ์ ํํ๋ก ์ฌ๋ฌ๋ฒ ๋ฐ๋ณต์ ํ๊ณ ์ถ์๋ ์ฝ๋ฐฑํจ์๋ฅผ ์ค์ฒฉํ์ฌ ๋ค์๊ณผ ๊ฐ์ด ๊ตฌํํ ์ ์๋ค.
function increase(number,callback){
setTimeout(()=>{
constresult=number+10;
if(callback){
callback(result);
}
},1000);
}
console.log('์์
์์');
increase(0,result=>{
console.log(result);
increase(result, result=>{
console.log(result);
increase(result,result=>{
console.log(result);
increase(result,result=>{
console.log(result);
console.log('์์
์๋ฃ');
});
});
});
});
๋ค! ์ด๋ฐ ์ฝ๋๋ฅผ ์ฝ๋ฐฑ์ง์ฅ์ด๋ผ๊ณ ํฉ๋๋ค!
์ฝ๋ฐฑ์ง์ฅ
์ฝ๋ฐฑ, ์ฝ๋ฐฑ, ์ฝ๋ฐฑ์ ๋ฐ๋ณต์ผ๋ก depth๊ฐ ๊น์ด์ง๋ ์ฝ๋๋ฅผ ์ฝ๋ฐฑ์ง์ฅ์ด๋ผ๊ณ ๋ถ๋ฅธ๋ค
์ด๋ฌํ ์ฝ๋๋ ๊ฐ๋ ์ฑ์ ๋งค์ฐ ๋จ์ด๋จ๋ฆฌ๋ฏ๋ก ์ง์ํด์ผํ๋ค.
// ์ฝ๋ฐฑ์ง์ฅ, ๊ฐ๋
์ฑ์ด ๋จ์ด์ง
$.get('url', function (response) {
parseValue(response, fuction(id) {
auth(id, function (result) {
display(result, function (text) {
console.log(text)
})
})
})
})
Promise
์ฝ๋ฐฑ์ง์ฅ ๊ฐ์ ์ฝ๋๋ฅผ ํด๊ฒฐํ๋ ๋ฐฉ์์ผ๋ก ES6์ ๋์ ๋ ๊ธฐ๋ฅ์ด๋ค (IE์๋ ..)
promise ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ์ฌ ๋น๋๊ธฐ ์์ ์ด ์๋ฃ๋ ํ(์ฑ๊ณต ํน์ ์คํจ) ๊ฒฐ๊ณผ๊ฐ์ ๋ฐ์ ์ ์์ด ์ดํ ์ฒ๋ฆฌ๋ฅผ ์ฝ๊ฒ ์ปจํธ๋กคํ ์ ์๋ค.
Promise๋ ํจ์๋ฅผ ์ธ์๋ก ๋ฐ์ผ๋ฉฐ ์ธ์๋ก ๋ค์ด์จ ํจ์๋ ๋ค์ resolve(๋น๋๊ธฐ ์ฒ๋ฆฌ ์ฑ๊ณต)์ reject(๋น๋๊ธฐ ์ฒ๋ฆฌ ์คํจ) 2๊ฐ์ ํจ์๋ฅผ ์ธ์๋ก ๋ฐ๊ฒ ๋๋ค.
resolve ์ then ๋ฉ์๋, reject ์ catch ๋ฉ์๋์ ์ธ์๋ก ๋์ด๊ฐ๋ค.
function increase(number){
const promise=newPromise((resolve,reject)=>{
// resolve๋์ฑ๊ณต, reject๋์คํจ
setTimeout(()=>{
const result=number+10;
if(result>50){
// 50๋ณด๋ค๋์ผ๋ฉด์๋ฌ๋ฐ์์ํค๊ธฐ
const e=newError('NumberTooBig');
return reject(e);
}
resolve(result);// number๊ฐ์ +10ํ์ฑ๊ณต์ฒ๋ฆฌ
},1000);
});
return promise;
}
increase(0).then(number=>{
// Promise์์ resolve๋๊ฐ์ .then์ํตํด๋ฐ์์ฌ์์์
console.log(number);
return increase(number);
// Promise๋ฅผ๋ฆฌํดํ๋ฉด
})
.then(number=>{
//๋ .then์ผ๋ก์ฒ๋ฆฌ๊ฐ๋ฅ
console.log(number);
return increase(number);
})
.then(number=>{
console.log(number);
return increase(number);
})
.then(number=>{
console.log(number);
return increase(number);
})
.then(number=>{
console.log(number);
return increase(number);
})
.catch(e=>{//๋์ค์์๋ฌ๊ฐ๋ฐ์ํ๋ค๋ฉด .catch๋ฅผํตํด์์์์
console.log(e);
});