동기와 비동기

고유·2022년 3월 18일
2

자바스크립트

목록 보기
6/6

1. 동기(Synchronous)

1) 정의

  • 코드를 실행시키고 그 결과값을 받을 때 까지 기다린 후 다음 코드를 실행하는 처리방식을 말한다.
  • 동기식에서 결과를 기다리는 과정을 blocking이라고 한다.

2) 특징

  • 일반적으로 코드가 처리되는 방법이 동기이다.
  • 단, 함수가 하는 일이 많은 경우 그 처리가 끝날 때 까지 다음 코드의 실행이 안된다면 문제가 된다.
  • 따라서 선행 함수로 얻은 값이 그 다음 코드에 반드시 필요한 경우 동기식으로 작성한다.

2. 비동기(Asynchronous)

1) 정의

  • 코드를 실행시키고 그 결과값을 언제 받을지 모른 상태로 다음 코드를 실행시킨다.
  • 비동기식에서 결과를 기다리지 않는 것을 non-blocking이라고 한다.

2) 특징

  • 어떤 함수를 실행시키고 결과를 얻기 전이라도 다음 코드로 넘어간다.
  • 그 결과를 받아주는 함수를 콜백함수라고 한다.
  • 비동기적 코드의 실행 결과는 동기적 코드가 전부 실행 되고나서 값을 반환한다.

3) 비동기처리를 해야 하는 이유

그 중에서도 async/await를 쓰자

  • 자바스크립트는 기본적으로 코드를 동기처리 한다.
  • 시간이 오래 걸리는 코드를 비동기 처리를 전혀 하지 않으면, 다음 코드에 문제가 발생할 수 있음
  • 예를 들어 서버에서 유저의 data를 받아와서 웹페이지에 출력하는 시나리오가 있다.
  • data를 받아 오는데 10초가 걸림, 근데 비동기 처리를 안하면 텅 빈 data를 출력 해버린다.
  • 비동기 처리를 하면 data를 가져올 때 까지 적어도 데이터가 없다는 문구 정도는 띄워줄 수 있는 거니까 필요하다.
  • 즉, 비동기 처리가 있는 경우 언제 유저의 data를 받아 올진 모르겠지만 콜백함수만 등록해 놓으면 유저의 data가 준비되는 대로 등록해 놓은 콜백함수를 불러준다는 뜻이다.

4) AJAX

  • 자바스크립트를 이용해 비동기적으로 서버와 브라우저가 데이터를 교환할 수 있는 통신 방식
  • 새로운 데이터를 불러올 때 페이지를 refresh하지 않고, 부분적으로만 갱신해서 데이터를 불러올 수 있음

3. 비동기처리 종류

콜백함수는 빼고 보자

1) Promise

① 정의

  • 프로미스는 JS에서 제공하는 비동기 코드를 간편하게 처리할 수 있게 도와주는 객체(사실 모든 비동기처리가 그러한 목적임)

② 로직

// 프로미스를 사용하면 반드시 resolve와 reject를 호출해야 함
const condition = true;
const promise = new Promise((resolve, reject) => {
  if (condition) {
    resolve('resolved');
  } else {
    reject('rejected');
  }
});

promise
  .then((res) => {
    console.log(res);
  })
  .catch((error) => {
    console.error(error);
  });
  • 프로미스는 어떤 기능을 실행하고 나서 정상적으로 동작하면, 성공의 메시지와 함께 처리된 결과값을 전달해 준다.
  • 그러나 기능을 수행하다 문제가 발생하면 error를 전달해 준다.
  • 실행 -> 보류(pending) -> 이행(fulfill) or 에러(reject)

2) async / await

① 정의

  • async 와 await는 Promise를 간결/간편하고 동기적으로 실행되는것 처럼 보이게 만들어주는 비동기처리 API
  • 가장 최근에 나온 비동기 처리 문법으로 기존의 callback 이나 Promise 의 단점을 해소하고자 만들어졌다.
  • callback 이나 Promise 의 경우에 단점은 꼬리에 꼬리를 무는 코드가 나올 수도 있다는 부분이다. 흔히들 콜백 지옥, then() 지옥이라고 부른다.
  • await 를 통해 Promise 반환 값을 받아 올 수 있다.

② 로직


const condition = true;
const promise = new Promise((resolve, reject) => {
  if (condition) {
    resolve('resolved');
  } else {
    reject('rejected');
  }
});  

const getResult = async() => {
  try {
    const result = await promise;
    console.log(result);
  } catch (err) {
    console.error(err);
  }
}
  • 하지만 async/await 를 사용하기 위해서는 선행되어야 하는 조건이 있는데, await 는 async 함수 안에서만 동작한다.
  • 일반적으로 await의 대상이 되는 비동기 처리 코드는 Axios 등 프로미스를 반환하는 함수다.
  • async 함수 자체는 비동기적으로 처리되나 그 async 함수 내의 await는 동기적으로 처리되므로 함수 내에서 값을 구하기 전까지는 다음 코드로 넘어가지 않는다.

3) Promise vs async/await 차이점

가독성 측면에서 후자 승

① 에러 핸들링

  • Promise 를 활용할 시에는 .catch() 문을 통해 에러 핸들링이 가능하다.
  • async/await 은 에러 핸들링 할 수 있는 기능이 없어 try-catch() 문을 활용해야 한다.

② 코드 가독성

  • Promise의 .then() 지옥의 가능성
  • 코드가 길어지면 길어질수록, async/await 를 활용한 코드가 가독성이 좋다.
  • async/await 은 비동기 코드가 동기 코드처럼 읽히게 해준다. 코드 흐름을 이해 하기 쉽다.
profile
프론트엔드

1개의 댓글

comment-user-thumbnail
2023년 2월 22일

감사합니다!

답글 달기