동기

순차적으로 한번에 하나씩 수행하는 것

엔진은 싱글쓰레드 – 한번에 하나씩 순차적으로 수행

  • 작업 1이 오래걸리는 작업이라면 작업2, 작업3은 작업1이 끝날때까지 기다려야 한다
  • 작업1이 수행되는동안 blocking 된다
<script>
console.log("1");
console.log("2");
console.log("3");
</script>
더보기

실행 순서

1

2

3

비동기

  • 작업1 을 WEPAPI로 넘기고( 2초가 지난다음 실행)
  • 다음 작업2, 작업3이 곧바로 실행된다
<script>
setTimeout(function(){
console.log("1")
}, 3000);
console.log("2");
console.log("3");
</script>
더보기

실행순서

2

3

1

CallBack함수 - 동기

다른 함수의 인자로 전달되는 함수

fncall 이후의 함수가 나중에 출력됨

<script>
/*
function main(fncall){
console.log(fncall);
}
main(10);
main('hello');
*/
function main(fncall){
// fncall은 function을 전달 받음
// 나중에 호출한다
console.log("1");
//main()의 인자 로 받은 function를 호출 한다
fncall();
}
// main()함수 호출시 인자로 function()을 전달 , main() 함수에서 fncall변수로 받는다
main(function(){
console.log("2");
})
console.log("3");
</script>
더보기

실행순서

1

2

3

CallBack함수 - 비동기

콜백함수 적용 예제

게시판 리스트를 띄우기 위해 먼저 리스트를 가져오고 출력해야만 한다
만약에 리스트 출력시간이 2000ms가 걸릴 때 가져온 이후 출력하는 법

(틀린 예제)

더보기
<script>
function main() {
setTimeout(function(){
console.log("게시판 리스트 가져오기")
}, 2000);
}
main();
console.log("게시판 리스트 출력하기");
// 게시판 리스트 출력하기 부분을 콜백 함수로 처리 - 비동기 처리 함수 내에서 호출
</script>
출력 순서가 게시판 리스트가 먼저 출력되고 가져오기 때문에 순서가 맞지않기 때문에
출력하기를 콜백 함수로 호출해야한다

(올바른 예제)

<script>
// 비동기 처리(게시판 리스트 가져오기) 후 후처리를 콜백(게시판을 출력)을 통해서 처리
function main(fncall) {
setTimeout(function(){
console.log("게시판 리스트 가져오기")
// 콜백함수를 호출
fncall()
}, 2000);
}
// main함수 호출 - 인자로 function을 전달한다
main(function(){
console.log("게시판 리스트 출력하기");
});
</script>

적용 예제 (데이터 가져오기)

<script>
function getData(fncall) {
setTimeout(function(){
console.log("서버에서 데이터 받아옴");
// 서버에서 데이터 히어로를 받아왔다고 가정
fncall({name : "히어로"});
}, 2000);
}
// getData함수 호출 - 인자로 function을 전달한다
getData(function(data){
console.log(`후처리 데이터 ${data.name}`);
});
</script>

<script>
// 로그인 - 장바구니 - 결제하기
// 로그인 함수 정의
function login(username, fncall){
setTimeout( ()=>{
fncall(username);
}, 2000)
}
// 장바구니 함수 정의
function addToCart(product, fncall){
setTimeout(()=>{
fncall(product);
}, 3000)
}
// 결제함수 정의
function makePayment(cardNo, product, fncall){
setTimeout(()=>{
fncall(cardNo, product);
},1000)
}
/* 호출순서와 응답순서는 다르다(비동기)
login('오리',username =>{
console.log(`${username}님 안녕하세요`);
})
addToCart('감자',product => {
console.log(`${product}를 장바구니에 넣었습니다`);
})
makePayment('123412341234','감자',(cardNumber, product) =>{
console.log(`${cardNumber.slice(0,4)}*******으로 ${product}를 구매 했어요`);
})
*/
// 장바구니 결제 > 리뷰작성 > 쿠폰받기
login('오리',username =>{
console.log(`${username}님 안녕하세요`);
addToCart('감자',product => {
console.log(`${product}를 장바구니에 넣었습니다`);
makePayment('123412341234','감자',(cardNumber, product) =>{
console.log(`${cardNumber.slice(0,4)}*******으로 ${product}를 구매 했어요`);
/*
review('맛나는 감자',function(){
console.log(`내가 쓴 리뷰 : ${review}`);
getCoupon(function(){
})
})
콜백 지옥 */
})
})
})
</script>

각 작업은 이전의 작업에 의존한다 - 이전 작업 완료 후에 다음 작업이 수행된다

콜백 함수를 이용하여 다음 작업을 호출한다

코드의 가독성이 떨어지며(복잡하며) 유지보수가 어렵다

더 많은 기능을 필요할 때 마다 콜백 함수를 추가하게 된다 >> 콜백지옥

콜백지옥 해결

promise객체를 활용한다