[JavaScript] 자바스크립트 동기와 비동기

호이·2023년 2월 28일

JavaScript

목록 보기
1/4

1. 동기와 비동기

비동기의 반대말은 동기이다. 동기는 어떠한 일을 순차적으로 처리하지만 비동기는 순차적으로 처리하지 않는 것을 말한다. 일반적인 예를 들어 설명하면 다음과 같다.

  • 동기: 짜장면 배달부가 A집과 B집을 배달해야 하는데 A집에서 짜장면을 다 먹은 것을 기다린 후 빈 그릇을 가지고 B집으로 배달하는 상황
  • 비동기: 짜장면 배달부가 A집과 B집을 배달해야 하는데 A집에서 짜장면을 다 먹을 때 까지 기다리지 않고 B집으로 배달하는 상황

당연하지만 일반적으로 우리가 짜장면을 다 먹는 시간이 있기 때문에 짜장면 배달부는 짜장면만 배달하고 먹는 시간을 기다리지 않는다. 나중에 우리가 빈 그릇을 밖에 두면 배달부는 밀린 배달 업무를 완료한 후 빈 그릇을 회수한다. 우리 일상생활에서도 이미 비동기적으로 일을 하고 있었다. 자바스크립트는 원래 동기적으로 코드를 실행하지만 경우에 따라서 비동기적으로 처리되는 경우가 있다. 불필요하게 비동기적으로 처리되는 것을 동기적으로 처리하게 코드를 작성해야 한다.

2. 비동기 처리

비동기를 동기적으로 처리하는 방법은 3가지가 있다.

  • callback: 다른 함수의 인자 값으로 받는 함수
  • Promise: 알려지지 않았을 수도 있는 값을 위한 대리자
  • async / await: 비동기를 동기식으로 처리하는 기법

1. callback

콜백함수는 다른 함수의 인 값으로 받는 함수를 의미한다. 예를 들어 자바스크립트에서 사용하는 setTimeoutaddEventListener가 있다. 두 함수는 인자 값으로 함수를 받는 데 이를 콜백함수라고 부른다. 콜백함수를 생성하여 사용할 수도 있다. 다음과 같이 코드를 작성하면 된다.

function first(callback) {
  console.log("first함수");
  callback();
}
first(() => {
  console.log("콜백함수");
});

함수를 생성할 때 인자 값을 받아서 함수로 실행하도록 생성하면 된다. 콜백함수를 사용하는 이유는 자주 사용하는 함수를 실행한 뒤 개발자가 원하는 함수를 실행하기 위해 사용한다.

2. Promise

콜백함수를 계속 사용하다 보면 코드가 오른쪽으로 기울어지는 모양을 가지게 된다. 흔히 골백지옥이라고 부른다. 콜백지옥에 빠지게 되면 코드 해석도 어렵고 오류가 발생할 경우는 오류를 찾아내기 어렵다. 이러한 단점을 보완하기 위해 사용하는 것이 promise이다. promise는 다음과 같이 사용할 수 있다.

function promise() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("완료");
    }, 2000);
  });
}
promise().then((value) => {
  console.log(value);
});

Promise객체를 생성한 후 resolvereject를 인자 값으로 받는 함수를 생성한 후 비동기 처리할 로직을 작성하면 된다. Promise객체는 3가지의 상태를 갖는다.

  • 대기(pending): 이행하지도, 거부하지도 않은 초기 상태.
  • 이행(fulfilled): 연산이 성공적으로 완료됨.
  • 거부(rejected): 연산이 실패함.

아무것도 반환하지 않으면 대기상태이고 resolve를 반환하면 이행상태가 되며 reject를 반환하면 거부상태가 된다.

3. async / await

비동기를 동기적으로 처리하는 기법이다. 비동기 함수를 처리하는 것은 Promise객체가 하고 async / await는 비동기적으로 진행되는 것을 동기적으로 처리하게 하는 기법이다. 다음과 같이 사용이 가능하다.

function sleep(ms) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log(ms / 1000 + "초 지남");
      resolve();
    }, ms);
  });
}
async function run() {
  console.log(1);
  await sleep(3000);
  console.log(2);
}
run();

async / await를 사용하지 않으면 1과 2을 출력하고 sleep함수가 실행되지만 사용을 하였다면 sleep함수의 실행을 기다리고 2가 출력된다.

profile
기억하기 싫어서 기록하는 작은 공간

0개의 댓글