[TIL / JavaScript] 비동기 처리와 콜백 함수

Changyun Go·2022년 2월 27일
0
post-thumbnail

콜백 함수를 통해 비동기 방식에서도 순차적으로 로직을 실행할 수 있다.

동기와 비동기

동기 방식

앞서 실행된 명령이 끝난 다음 순차적으로 다음 코드를 실행하는 것이다.

  • 설계가 간단하고 직관적이지만 결과가 주어질 때까지 아무 작업도 하지 못한다.

비동기 방식

앞서 실행된 명령이 끝날 때까지 기다리지 않고 다음 코드를 먼저 실행하는 것이다.

  • 설계가 복잡하지만 자원을 효율적으로 사용할 수 있다.
console.log(1);
console.log(2);
setTimeout(function () {
	console.log(3);
}, 5000);
console.log(4);

// 1 2 4 3

setTimeout 함수가 종료되는 것을 기다리지 않고, 바로 다음 코드인 console.log(4);를 실행한다.

  • 비동기 방식을 상황에 따라 순차적으로 동작할 수 있도록 하기 위해 비동기 처리 패턴을 사용한다.

콜백 함수를 이용한 비동기 처리

다음에 실행할 로직를 콜백 함수로 전달하여 로직이 끝났을 때 호출할 수 있다.

time초 후에 실행되는 함수 timer가 있다.

function timer (time, callback) {
  setTimeout(function () {
    callback();
  }, time);
}

timer(1000, function () {
	console.log('작업');
	timer(1000, function () {
		console.log('작업');
	});
});

// (1초) 작업 (1초) 작업

이어지는 timer 함수를 콜백 함수로 전달하여 순차적으로 동작을 실행한다.

콜백 지옥

만약 timer 함수를 100번 실행해야 한다면?

timer(1000, function () {
	console.log('작업');
	timer(1000, function () {
		console.log('작업');
		timer(1000, function () {
			console.log('작업');
      timer(1000, function () {
        console.log('작업');
        timer(1000, function () {
          console.log('작업');
          // ...
        });
      });
		});
	});
});

콜백 안에 콜백을 계속 무는 형식으로 코드가 작성되어 들여 쓰기가 심각하게 깊어지는 콜백 지옥이 발생한다.

  • 코드의 가독성과 재사용성이 현저하게 떨어진다.

해결 방법

기명 함수를 사용하면 콜백 지옥을 해결할 수 있다.

timer(1000, timer1);
function timer1 () {
  console.log('작업');
  timer(1000, timer2);
}
function timer2 () {
  console.log('작업');
  timer(1000, timer3);
}
function timer3 () {
  console.log('작업');
  timer(1000, timer4);
}
// ...
  • 로직마다 새로운 함수명을 지어야 한다.
  • 이전 로직에서 정의한 변수를 다음 로직에서 재사용할 수 없다.

ES6부터는 Promise, ES8부터는 async function으로 더욱 쉽게 해결할 수 있다.

Reference


0개의 댓글