[SeSAC x 코딩온] 웹 풀스택 회고 10 | 비동기 처리

HyeKong·2023년 8월 15일
0

비동기처리란

특정 코드 연산이 끝날 때까지 기다려주지 않고 다음 코드를 먼저 실행하는 것

비동기 처리 방법

  1. callback
  2. promise
  3. async await

callback 함수

파라미터로 대입되는 함수
다른 함수의 실행 후 실행되는 함수
비동기 방식 함수 => 동기 처리 위해
보통 함수 선언 후 함수 타입 파라미터를 맨 마지막에 하나 더 선언 해주는 방식으로 정의

  • 예제
function goMart() {
  console.log("마트에 가서 어떤 음료를 살지 고민한다.");
}
function pickDrink() {
  setTimeout(function () {
    console.log("고민끝!");
    product = "제로콜라";
    price = 2000;
  }, 3000);
}
function pay(product, price) {
  console.log(`상품명: ${product}, 가격: ${price}`);
}
let product;
let price;

다음 함수를

function goMart() {
  console.log("마트에 가서 어떤 음료를 살지 고민한다.");
}
function pickDrink(callback) {
  // callback 매개변수: 콜백함수 의미
  setTimeout(function () {
    console.log("고민끝!");
    product = "제로콜라";
    price = 2000;
    callback(product, price); //매개변수로 넘긴 콜백함수 실행
  }, 3000);
}
function pay(product, price) {
  console.log(`상품명: ${product}, 가격: ${price}`);
}

콜백 지옥

콜백 함수가 반복되어 코드의 들여쓰기가 너무 깊어지는 현상

ㅋㅋㅋㅋ 이런..!

  • 예제
setTimeout(function () {
        document.body.style.backgroundColor = "red";
        setTimeout(function () {
          document.body.style.backgroundColor = "ornage";
          setTimeout(function () {
            document.body.style.backgroundColor = "yellow";
            setTimeout(function () {
              document.body.style.backgroundColor = "green";
              setTimeout(function () {
                document.body.style.backgroundColor = "blue";
              }, 1000);
            }, 1000);
          }, 1000);
        }, 1000);
      }, 1000);

Promise

비동기 함수를 동기 처리하기 위해 만들어진 객체
성공 | 실패 분리 반환
비동기 작업 완료 이후에 다음 작업 연결시켜 진행 가능
new Promise로 만들어 사용

  • 이 때 executor가 자동 실행
  • executor는 인수로 resolve, reject 가짐
  • 성공, 실패 대한 결과는 then, catch 로 이어받아 처리 가능
    => 성공이든 실패든 무언가의 "최종 결과"

Promise 상태


구조를 다이어그램으로 그려봤다.
복잡하네...

Promise가 갖는 두 가지의 콜백 함수


resolve(value): 작업이 fulfilled된 경우, 그 결과를 value와 함께 호출
reject(error) : rejected 시 error와 함께 호출


다이어그램을 그려보았다.

  • 예제
function promise1(flag) {
  return new Promise(function (resolve, reject) {
    if (flag) {
      resolve(
        `현재 프로미스의 상태는 fulfilled! then 메서드로 연결, 이 때 flag 값은 ${flag}`
      );
    } else {
      reject(
        `현재 프로미스의 상태는 rejected! catch 메서드로 연결, 이 때 flag 값은 ${flag}`
      );
    }
  });
}
//2. promise 사용(소비) 코드
flag = true;
promise1(flag)
  .then(function (result) {
    console.log(result);
  })
  .catch(function (error) {
    console.log(error);
  });

Async / Await

async

  • 항상 Promise 반환
  • Promise가 아닌 값을 반환해도 Promise로 감싸서 반환
  • 비동기 실행을 알림

await

  • 성공/실패로 프로미스 객체 실행 완료 되기를 기다림
  • Promise 앞에 붙어 Promise가 다 처리될 때까지 기다리는 역할
  • async 키워드를 사용한 함수 안에서만 await 키워드 사용 가능

실습

  1. 다음 콜백 함수 promise로 바꾸기
function call(name, cb) {
  setTimeout(function () {
    console.log(name);
    cb(name);
  }, 1000);
}
function back(cb) {
  setTimeout(function () {
    console.log("back");
    cb("back");
  }, 1000);
}
function hell(cb) {
  setTimeout(function () {
    cb("callback hell");
  }, 1000);
}

call("kim", function (name) {
  console.log(name + "반가워");
  back(function (txt) {
    console.log(txt + "를 실행했구나");
    hell(function (msg) {
      console.log("여기는" + msg);
    });
  });
});
  • 정답
function call(name) {
  return new Promise(function (res, rej) {
    setTimeout(function () {
      // console.log(name);
      res(name);
    }, 1000);
  });
}
function back() {
  return new Promise(function (res, rej) {
    setTimeout(function () {
      // console.log("back");
      res("back");
    }, 1000);
  });
}
function hell() {
  return new Promise(function (res, rej) {
    setTimeout(function () {
      // console.log("callback Hell");
      res("callback Hell");
    }, 1000);
  });
}
call("Kang")
  .then(function (result) {
    console.log(result + "반가워");
    return back(result);
  })
  .then(function (result) {
    console.log(result + "를 실행했구나");
    return hell(result);
  })
  .then(function (result) {
    console.log("여기는" + result);
    return result;
  })
  .catch(function (error) {
    console.log(error);
  });
  1. 1번에서 Promise로 바꿨던 코드를 async/await로 바꾸기
async function exec() {
  let user = await call("Kang");
  console.log(user + "반가워");
  let prc = await back();
  console.log(prc + "를 실행했구나");
  let here = await hell();
  console.log("여기는 " + here);
}
exec();
  1. 콜백지옥 예제 코드를 promise로 바꾸기
const body = document.body;
      //1초 뒤에 body 태그 색상 빨강색 변경
      function goRed() {
        return new Promise(function (res, rej) {
          setTimeout(function () {
            body.style.backgroundColor = "red";
            res();
          }, 1000);
        });
      }
      // 2. 1초 뒤에 body 태그의 색상을 빨 -> 1초 뒤 주 -> ... -> 1초 뒤에 파란색
      function goOrange() {
        return new Promise(function (res, rej) {
          setTimeout(function () {
            body.style.backgroundColor = "orange";
            res();
          }, 1000);
        });
      }
      function goYellow() {
        return new Promise(function (res, rej) {
          setTimeout(function () {
            body.style.backgroundColor = "yellow";
            res();
          }, 1000);
        });
      }
      function goGreen(callback) {
        return new Promise(function (res, rej) {
          setTimeout(function () {
            body.style.backgroundColor = "green";
            res();
          }, 1000);
        });
      }
      function goBlue() {
        return new Promise(function (res, rej) {
          setTimeout(function () {
            body.style.backgroundColor = "blue";
            res();
          }, 1000);
        });
      }
      goRed()
        .then(function (result) {
          return goOrange();
        })
        .then((result) => goYellow())
        .then((result) => goGreen())
        .then((result) => goBlue());

어렵내요....

1개의 댓글

comment-user-thumbnail
2023년 8월 15일

유익한 글이었습니다.

답글 달기