웹프로그래밍/jQuery

[jQuery] 동기 / 비동기 CallBack

아잠만_ 2024. 5. 23. 14:27

동기

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

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

  • 작업 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객체를 활용한다