[TIL] 동기와 비동기, Node.js의 비동기

·2023년 6월 8일
0

TIL

목록 보기
3/7
post-thumbnail

✔️동기 (synchronous)

  • 요청과 결과가 동시에 발생
    → 요청을 하면 시간이 얼마나 걸리든지 상관없이 요청한 자리에서 결과가 주어져야 한다.
    → 즉, 요청에 따른 응답을 사용자에게 다시 전송하기 전까지 사용자는 다른 활동이 불가능하다.

✔️비동기 (asynchronous)

  • 요청과 결과가 동시에 발생X
  • 시간이 오래걸리는 일을 요청했을 경우, 백그라운드에서 작업하고있음
    → 사용자는 요청에 따른 응답을 계속 기다리지 않아도 되며, 다른 외부 활동을 수행하여도 되고 서버에게 다른 요청을 보내도 상관없다.

✔️동기와 비동기 비교

동기의 장단점

장점: 설계 간단, 직관적
단점: 결과가 주어질때까지 계속 하나의 요청에 대한 응답값을 대기해야함

비동기의 장단점

장점: 요청에 따른 결과를 기다리지 않고 다른 작업 수행 가능
단점: 동기식보다 설계 복잡

비동기의 문제

이러한 점을 봤을 때, 당연히 비동기가 좋지 않냐는 생각이 들것이다. 하지만 하나의 예시를 들어보자.

  1. 빨래를 세탁기에 돌린다.
  2. 완성된 빨래를 건조기에 돌린다.
  3. 건조가 완성된 옷들을 정리하여 옷장에 넣는다.

위와 같은 순서로 집안일을 할때, 비동기식으로 진행해보자.

  1. 빨래를 세탁기에 돌린다. → 큰 값이므로 백그라운드로 이동
  2. 빨래를 건조기에 돌린다. → 세탁기가 다 돌아가지 않는 상태로, 건조기에 돌릴 옷이 존재X
  3. 세탁기 결과물 없이 건조기가 돌아감
  4. 에러 발생 or 건조기 돌려도 결과물이 존재X

이와 같은 에러가 발생할 수 있다. 그래서 작업에 따라 동기식으로 진행할지, 비동기식으로 진행할지 판단할 필요가 있다.


✔️비동기식 방식

위와 같은 문제로 인해 나온 비동기처리 방식이 있다.
1. 콜백함수
2. promise (resolve, reject)
3. then & catch
4. async & await

1. 콜백함수

콜백함수: 나중에 실행되는 함수로, 비동기 작업이 끝난 후 실행되는 함수

setTimeout((arg)=>{
    console.log(arg)
    
    setTimeout((arg)=>{
        console.log(arg)

        setTimeout((arg)=>{
            console.log(arg)

            setTimeout((arg)=>{
                console.log(arg)

            }, 1000, "네번째 콜백")
        }, 1000, "세번째 콜백")
    }, 1000, "두번째 콜백")
}, 1000, "첫번째 콜백")

하지만 연속적인 비동기 함수의 호출과 처리는 수많은 callback 함수를 필요로 하고, 이로 인해 가독성이 안좋아진다. 이러한 문제를 Callback Hell이라고 부른다.
이러한 Callback Hell의 문제로 promise 객체가 나왔다.

2. promise(resolve, reject) + then, catch

promise 객체는 콜백함수의 callback hell을 해결하기 위해 나왔다. callback과 promise를 통해 짜인 코드를 비교해보자.

Callback

/* callback */
function add10(a, callback){
   setTimeout(() => callback(a + 10), 100);
}

add10(5, res => {
   add10(res, res => {
      add10(res, res => {
         console.log(res); //35
      }); // Callback Hell...
   });
});

Promise

/* promise */
function add20(a){
   return new Promise(resolve => setTimeout(() => resolve(a + 20), 100));
}

add20(5)
   .then(add20)
   .then(add20)
   .then(console.log); //65

Promise는 Callback과 달리 결과를 값으로 받아서 저장할 수 있다. 즉, Promise는 반환만 하면 되며, 따로 Callback 함수를 받을 필요가 없다. 그래서 Promise는 결과 그 자체를 값으로 받기 때문에, 연속으로 실행하는 코드에선 then() 을 이용한다.

3. async & await

awaitasync가 붙어있는 함수 내부에서만 사용할 수 있으며 비동기 함수가 리턴하는 Promise로부터 결과값을 추출해준다. 즉, await를 사용하면 일반 비동기처리처럼 바로 실행이 다음 라인으로 넘어가는 것이 아니라 결과값을 얻을 수 있을때까지 기다려준다.

async function 함수명() {
  await 비동기_처리_메서드_명();
}

참고자료

비동기 처리를 위한 Promise 객체
(TIL) 동기, 비동기와 Node.js에서의 비동기처리 방법

0개의 댓글