Callback과 Promise
2022. 11. 23. 21:22ㆍWEB개발/TIL
반응형
Callback(콜백)
: 함수가 끝난 뒤 실행되는 함수
- 함수를 만들 때 paramater로 함수를 받아서 사용
Callback함수 사용하기
Callback함수를 사용하지 않은 코드
function func1() {
console.log("첫 번째 출력");
setTimeout (function() {
console.log("두 번째 출력");
},2000);
}
function func2() {
console.log("세 번째 출력");
}
func1();
func2();//
// 결과
첫 번째 출력
세 번째 출력
두 번째 출력
- setTimeout함수는 비동기 방식 → 콜백함수 사용
Callback함수를 사용한 코드
function func1(print,cb) {
console.log("첫 번째",print);
setTimeout (function() {
console.log("두 번째",print);
cb(print);
},2000);
}
function func2(print) {
console.log("세 번째",print);
}
func1("출력",function(print) {
func2(print);
})
// 결과
첫 번째 출력
두 번째 출력
세 번째 출력
Callback함수를 사용하는 이유?
: 비동기 방식으로 작성된 함수를 동기 처리 하기 위해 사용
Callback Hell(콜백 지옥)
: 함수의 매개변수로 넘겨지는 콜백 함수가 반복되어, 코드의 들여쓰기가 너무 깊어지는 현상
- 가독성이 낮음(=코드 수정 난이도 높음)
function login(id,cb) {
console.log("사용자 입장");
setTimeout(function() {
console.log(id,"님 로그인 성공!");
cb(id,);
},1500);
}
function listloading(id,cb) {
setTimeout(function() {
console.log(id,"님의 music playlist");
var mlist = ["antifragile","better","best part"];
console.log(mlist);
cb(mlist);
},1500);
}
function select(mlist,cb) {
setTimeout(function() {
console.log('"',mlist[2],'" 노래 선택!');
cb(mlist[2]);
},1500);
}
function play(play) {
setTimeout(function() {
console.log('"',play,'" 노래 재생 시작♪');
},1500);
}
login('nana',function(user) {
listloading(user,function(list) {
select(list,function(choose) {
play(choose);
})
})
})
// 결과
사용자 입장
nana 님 로그인 성공!
nana 님의 music playlist
[ 'antifragile', 'better', 'best part' ]
" best part " 노래 선택!
" best part " 노래 재생 시작♪
Promise(프로미스)
: callbackhell로 인한 복잡도 증가와 예외처리의 어려움을 해결하기 위해 만들어진 것
- 비동기작업에서 성공과 실패를 분리해 메소드를 수행
- resolve(value): 일이 성공적으로 끝난 경우
- promise를 실행한 곳의 then으로 들어감
- reject(error): 에러가 발생한 경우(일이 성공적으로 끝나지 않은 경우)
- promise를 실행한 곳의 catch로 들어감
Promise 기본 문법
new Promise(function(resolve, reject){
// resolve: 함수형태, 성공했을 때 실행
// reiect: 함수형태, 실패 혹은 에러 처리를 할 때 사용
});
Promise 사용하기
Case1)
function func1() {
return new Promise(function(resolve,reject) {
resolve("성공!");
});
}
console.log(func1()); // Promise { '성공!' }
func1().then(function(result) {
console.log(result); // 성공!; then은 promise의 값을 리턴함
})
Case2)
function func2() {
return new Promise(function(resolve,reject) {
setTimeout(function() {
resolve("성공!!");
},2000);
});
}
console.log(func2()); // Promise { <pending> }
func2().then(function(result) {
console.log(result); // 성공!!; 2초 후에 출력됨
})
- setTimeout함수는 비동기이기 때문에 pending상태로 출력됨
- fulfilled상태가 되면 then함수 실행됨(2초 후 “성공!!”출력)
→ 비동기를 동기처럼 사용할 수 있게함.
Promise의 상태
- pending: promise를 수행 중인 상태
- fulfilled: promise가 resolve된 상태
- rejected: promise가 지켜지지 못한 상태
- settled: fulfilled 혹은 rejected로 결론이 난 상태
.then()과 .catch()
Case1) 첫 번째 콜백 함수(reslove)가 true일 경우, 첫 번째 함수 동작
Case2) 두 번째 콜백 함수(reject)가 true일 경우, 두 번째 함수 동작
Case3) then함수에 동작해야 할(조건에 충족한) 함수가 없을 경우, catch함수 동작
- then함수가 먼저 처리할 경우, catch함수는 동작하지 않음
function func4(nana) {
return new Promise(function(resolve,reject){
if (nana) {
resolve("nana는 true");
} else {
reject("nana는 false");
}
});
}
// case1
func4(true)
.then(function(nana) {
console.log(nana);
}, function(nana) {
console.log(nana);
});
// case2
func4(false)
.then(function(nana) {
console.log(nana);
}, function(nana) {
console.log(nana);
});
// case3
func4(false)
.then(function(nana) {
console.log(nana);
})
.catch(function(nana) {
console.log(nana);
});//ruf
// 결과
nana는 true
nana는 false
nana는 false
Chaining(체이닝)
: 코드를 더 효율적으로 작성하기 위해 사용
- callbackhell에 비해 가독성이 높으며, 코드 수정을 쉽게 할 수 있음
function func3() {
return new Promise(function(resolve, reject) {
resolve("hello");
})
}
func3()
.then(function(hello) {
console.log(hello);
return "hi";
})
.then(function(hi){
console.log(hi);
});
// 결과
hello
hi
Callbackhell에서 작성했던 코드 Promise로 작성해보기
function login(id) {
return new Promise(function(resolve,reject) {
console.log("사용자 입장");
setTimeout(function() {
console.log(id,"님 로그인 성공!");
resolve(id);
},1500);
});
}
function listloading(id) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
console.log(id,"님의 music playlist");
var mlist = ["antifragile","better","best part"];
console.log(mlist);
resolve(mlist);
},1500);
});
}
function select(mlist) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
console.log('"',mlist[2],'" 노래 선택!');
resolve(mlist[2]);
},1500);
});
}
function play(play) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
console.log('"',play,'" 노래 재생 시작♪');
},1500);
});
}
login('nana')
.then(function(user) {
return listloading(user);
})
.then(function(list) {
return select(list);
})
.then(function(choose) {
return play(choose);
});
// 결과
사용자 입장
nana 님 로그인 성공!
nana 님의 music playlist
[ 'antifragile', 'better', 'best part' ]
" best part " 노래 선택!
" best part " 노래 재생 시작♪
반응형
'WEB개발 > TIL' 카테고리의 다른 글
http모듈 (0) | 2022.11.23 |
---|---|
fs모듈(FileSystem Module) (0) | 2022.11.23 |
Class, Object, Instance (0) | 2022.11.21 |
구조분해 할당(Destructuring assignment) (0) | 2022.11.21 |
Node.js(module) (0) | 2022.11.21 |