[javascript] 비동기 호출

Hyebin·2021년 4월 2일
0

Javascript

목록 보기
15/27
post-thumbnail

동기(Syncronous) VS 비동기(Asynchronous)

동기와 비동기의 큰 차이는 실행순서에 있다.

  • 동기 호출
    요청을 보낸 후 해당 요청의 응답을 받아야 다음 동작을 실행한다. 즉, 요청에 대한 결과가 동시에 일어난다. (blocking)
  • 비동기 호출
    요청을 보낸 후 응답과 관계없이 다음 동작을 실행할 수 있는 방식을 말한다. 즉, 요청에 대한 결과가 동시에 일어나지 않는다.(non-blocking)

비동기 호출의 예

실생활에서 보는 동기와 비동기 ⏰

내가 만약 음식점에서 주문을 위해 줄을 서 있는데, 앞 사람이 음식을 주문하고, 주문한 음식이 나올 때까지 줄서서 기다리며 주문조차 할 수 없다면 그 음식점은 망할게 분명하다. (특히나 성격 급한 한국에서 ☠️)

위와 같은 상황을 "동기적인 상황"이라 부른다.

"비동기적 상황"은 반대의 상황이다. 앞사람이 주문한 음식이 나오지 않았더라도 음식주문을 할 수 있다.
우리는 동기적 상황보다 비동기적 상황을 일상에서 더 익숙하게 접하게 된다.

동기적인 상황을 함수 코드로 아래처럼 나타낼 수 있다.
순차적으로 처리 되는 방식으로 진행된다.

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()으로 만들어보자.

  • 손님이 파스타를 주문한다.
  • 5초 뒤 주문하신 음식 나왔습니다.
  • 안녕히 가세요.
console.log('파스타 주세요');

setTimeout(function() {
  console.log('주문하신 음식 나왔습니다.');
}, 5000);

console.log('안녕히 가세요');

실행시켜보면 예상하지 못했던 결과로 출력되는 것을 볼 수 있다.
'안녕히 가세요'가 먼저 처리 되버린다.

  • 파스타 주세요
  • 안녕히 가세요
  • 주문하신 음식 나왔습니다.

원래 생각대로 처리되지 않았던 이유는 setTimeout()도 비동기 방식으로 실행되기 때문에 나타나는 현상인데, setTimeout()을 실행하고 5초 뒤에 처리되는 것이 아니라 바로 다음 코드인 console.log('안녕히 가세요');을 읽어 처리하기 때문이다.

그래서 순차적으로 비동기 처리를 하기위한 몇가지 방식들이 존재한다.

1. 콜백함수(callback)

콜백함수를 필요에 따라 비동기적으로 실행할 수 도 있다.
처리해야 하는 이벤트를 순차적으로 콜백함수에 넣어주는 방식으로 쓸 수 있다.

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) 
  });
});

콜백 함수를 연속적으로 사용할 때 발생하는 문제점들이 있다. 일명 콜백지옥이라 불리는데, 이를 개선하기 위해 나오는 방식들이 또 있다.
이건 심화 과정에서 배우면 추가 포스팅하기로!

0개의 댓글