동기와 비동기의 큰 차이는 실행순서에 있다.
내가 만약 음식점에서 주문을 위해 줄을 서 있는데, 앞 사람이 음식을 주문하고, 주문한 음식이 나올 때까지 줄서서 기다리며 주문조차 할 수 없다면 그 음식점은 망할게 분명하다. (특히나 성격 급한 한국에서 ☠️)
위와 같은 상황을 "동기적인 상황"이라 부른다.
"비동기적 상황"은 반대의 상황이다. 앞사람이 주문한 음식이 나오지 않았더라도 음식주문을 할 수 있다.
우리는 동기적 상황보다 비동기적 상황을 일상에서 더 익숙하게 접하게 된다.
동기적인 상황을 함수 코드로 아래처럼 나타낼 수 있다.
순차적으로 처리 되는 방식으로 진행된다.
function waitSync(ms) {
let start = Date.now();
let now = start;
while(now - start < ms) {
now = Date.now();
}
} //현재 시각과 시작 시각을 비교해 ms 범위 내에서 무한루프를 도는 blocking 함수
function eat(person, menu) {
console.log(`${person}은 ${menu}를 먹습니다.`);
}
function orderFoodSync(menu) {
console.log(`${menu}가 접수되었습니다.`);
waitSync(2000);
return menu;
}
let customers = [
{name: 'Tim',
request: 'pasta'
},
{name: 'me',
request: 'pizza'
}
];
customers.forEach(function(customer) {
let order = orderFoodSync(customer.request); //주문 받고 음식이 나올 때까지 텀이 있음
eat(customer.name, order); // 앞의 처리 결과가 끝나면 다시 주문 받음
});
비동기 처리를 위해 setTimeout()을 사용할 수 있다.
지정한 시간만큼 기다렸다가 로직을 실행한다.
아래 구조를 setTimeout()으로 만들어보자.
console.log('파스타 주세요');
setTimeout(function() {
console.log('주문하신 음식 나왔습니다.');
}, 5000);
console.log('안녕히 가세요');
실행시켜보면 예상하지 못했던 결과로 출력되는 것을 볼 수 있다.
'안녕히 가세요'가 먼저 처리 되버린다.
원래 생각대로 처리되지 않았던 이유는 setTimeout()도 비동기 방식으로 실행되기 때문에 나타나는 현상인데, setTimeout()을 실행하고 5초 뒤에 처리되는 것이 아니라 바로 다음 코드인 console.log('안녕히 가세요');
을 읽어 처리하기 때문이다.
그래서 순차적으로 비동기 처리를 하기위한 몇가지 방식들이 존재한다.
콜백함수를 필요에 따라 비동기적으로 실행할 수 도 있다.
처리해야 하는 이벤트를 순차적으로 콜백함수에 넣어주는 방식으로 쓸 수 있다.
function waitAsync(callback, ms) {
setTimeout(callback, ms); //특정 시간 이후에 callback 함수가 실행되도록
}
}
function eat(person, menu) {
console.log(`${person}은 ${menu}를 먹습니다.`);
}
function orderFoodSync(menu, callback) {
console.log(`${menu}가 접수되었습니다.`);
waitAsync(function() {
callback(menu)
}, 4000);
}
let customers = [
{name: 'Tim',
request: 'pasta'
},
{name: 'me',
request: 'pizza'
}
];
customers.forEach(function(customer) {
orderFoodSync(customer.request, function(menu) {
eat(customer.name, menu)
});
});
콜백 함수를 연속적으로 사용할 때 발생하는 문제점들이 있다. 일명 콜백지옥이라 불리는데, 이를 개선하기 위해 나오는 방식들이 또 있다.
이건 심화 과정에서 배우면 추가 포스팅하기로!