비동기 호출 (2) 동기(sync) vs 비동기(async)
비동기 호출 (1) callback 함수
비동기 호출 (2) 동기(sync) vs 비동기(async)
비동기 호출 (3) Timer API
Blocking vs Non-Blocking
✔️ Blocking
다른 작업을 하려면, 하던 작업을 멈춰야 함
요청에 대한 결과들이 동시에 일어남
✔️ Non-Blocking
다른 작업을 확인만 하고, 미룰 수 있음
요청에 대한 결과들이 동시에 일어나지 않음
Blocking을 전화, Non-Blocking을 문자에 비유해서 생각하면 좀 더 이해하기 쉽다. 전화는 하던 작업을 멈추고 받아야하지만, 문자는 확인만 한 후 답장을 미룰 수 있다. 이제 이 두 가지 개념을 바탕으로 동기적 처리, 비동기적 처리에 대해 알아보려고 한다. (블럭&논블럭는 함수호출과 관련된 개념이고, 동기&비동기는 행위와 관련된 개념이라 엄밀히는 다른 개념인데, 이에 대한 자세한 이야기는 여기에 친절하게 있어서 참고하면 좋을 것 같다.)
동기(synchronous) vs 비동기(asynchronous)
동기(sync)
현재 실행중인 코드부터 완료하고 다음 코드를 처리하는 방식이 '동기적 처리'이다. 바로바로 처리 가능한 대부분이 동기적인 코드에 해당한다. 👉🏻직렬 처리
비동기(async)
현재 실행 중인 코드가 완료된 지와는 상관없이, 바로 다음 코드로 넘어가는 방식이 '비동기적 처리'이다. 실행 보류, 대기 등과 관련된 코드들이 비동기적인 코드에 해당한다. 👉🏻병렬 처리
setTimeout : 특정 시간이 경과되기 전까지 함수 실행을 보류
addEventListner : 이벤트 발생 시에 함수를 실행하도록 대기
XMLHttpRequest : 웹 브라우저가 아닌 대상에 요청을 보내고, 응답이 왔을 때 함수를 실행하도록 대기
커피를 주문하는 상황을 생각해보자. 한 사람이 커피를 주문하고, 주문한 커피를 제공한 후, 다음 사람의 주문을 받는건 동기적 방식이라고 볼 수 있다. 반대로 모든 사람의 주문을 한번에 받고, 커피가 완성되는 대로 제공하는건 비동기적 방식이다.
동기적 방식을 사용하면 순서대로 처리되기 때문에 직관적이고 설계를 하기도 비교적 간단하다. 하지만 어떤 작업이 실행되면, 끝날 때 아무것도 하지 못하고 대기해야 한다는 단점이 있다. 이와 달리 비동기적 방식은 설계하기가 복잡하지만, 오래 걸리는 작업이 있더라도 그 동안 다른 작업을 수행 할 수 있기 때문에 더 효율적이라는 장점이 있다.
비동기 함수 전달 패턴
그렇다면 한번에 주문을 받는, 순차적으로 진행되지 않는 '비동기 처리'는 어떤식으로 구현할 수 있을까? 아래와 같이 비동기 함수를 전달하는 패턴 두 가지가 있다. callback함수 형태로 실행을 보류하거나, 어떤 이벤트를 등록해놓고 대기시키다가 이벤트 발생 시에 함수를 실행하도록 할수도 있다.
callback 패턴
let req = 'americano';
orderCoffeeAsync(req, function(res){
drink(res);
});
이벤트 등록 패턴
let req = 'americano';
orderCoffeeAsync(req).onready = function(res){
drink(res);
};
동기/비동기 방식의 차이점과 각각의 장단점, 그리고 비동기 함수를 사용하는 방법에 대해 알아봤다. 다음에는 setTimeout, setInterval 등의 비동기 호출 함수를 이용하는 타이머 API에 대해 알아보며 비동기 호출에 대한 이야기를 마치려고 한다.