sol의 개발로그

[javascript] 동기 / 비동기 (Resolve, Reject, error 핸들링) 본문

Javascript

[javascript] 동기 / 비동기 (Resolve, Reject, error 핸들링)

Soly_ 2023. 8. 20. 23:48

Resolve, Reject, error 핸들링

 

1. resolve : Promise 내부에서 사용되는 함수로 비동기 작업이 성공적으로 완료되었을 때 호출되는 콜백함수

작업성공 : resolve함수를 호출하고 작업의 결과를 인자로 넘겨준다. 이 결과값은 then() 메서드에서 처리된다.

작업 완료 " resolve함수를 호출하면 Promise 상태가 이행(Fulfilled) 상태로 변경되며 Promise는 성공적으로 완료된 것으로 간주되어 then메서드 내의 콜백함수가 실행된다.

2.  reject : 비동기 작업이 실패했을 때 호출되는 함수로, 오류 정보나 실패 사유를 인자로 넘겨준다 reject 함수를 호출하면  Promise의 상태가 거부(Rejected) 상태로 변경되며 이후 catch 메서드 내의 콜백 함수가 실행된다.

 

콜백패턴에서의 에러 핸들링

const delayAdd = (index, cb, errorCd) => {
  setTimeout(() => {
    if (index > 10) {
      errorCd(`${index}는 10보다 클 수 없습니다`);
      return;
    }
    console.log(index);
    cb(index + 1);
  }, 1000);
};

delayAdd(
  4,
  (res) => console.log(res),
  (err) => console.error(err)
);

// 4,5

const delayAdd = (index, cb, errorCd) => {
  setTimeout(() => {
    if (index > 10) {
      errorCd(`${index}는 10보다 클 수 없습니다`);
      return;
    }
    console.log(index);
    cb(index + 1);
  }, 1000);
};

delayAdd(
  11,
  (res) => console.log(res),
  (err) => console.error(err)
);

// 11은 10보다 클 수 없습니다.

Promise 에러 핸들링

const delayAdd = (index) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (index > 10) {
        reject(`${index}는 10보다 클 수 없습니다`);
        return;
      }
      console.log(index);
      resolve(index + 1);
    }, 1000);
  });
};

delayAdd(13)
  .then((res) => console.log(res))
  .catch((err) => console.error(err)); //13는 10보다 클 수 없습니다

delayAdd(4)
  .then((res) => console.log(res))
  .catch((err) => console.error(err)); // 4, 5

Promise 에러 핸들링 (aynce, await 패턴)

aynce에서의 에러핸들링은 try, catch문을 사용하여 핸들링 한다.

const delayAdd = (index) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (index > 10) {
        reject(`${index}는 10보다 클 수 없습니다`);
        return;
      }
      console.log(index);
      resolve(index + 1);
    }, 1000);
  });
};

// 하단과 같은 코드도 가능하지만
const wrap = async () => {
  const res = await delayAdd(2);
  console.log(res); 
};

wrap(); //2,3

// try, catch문을 사용하여 에러헨들링을 지향한다.
const wrap = async () => {
  try {
    const res = await delayAdd(2);
    console.log(res);
  } catch (err) {
    console.error(err);
  }
  try {
    const res = await delayAdd(125);
    console.log(res);
  } catch (err) {
    console.error(err);
  }
};

wrap();
//2,3
//125는 10보다 클 수 없습니다

 

 

Promise와 try, catch에서 사용하는 구문 중 실행성공, 실패와 상관없이 항상 실행하는 코드는?  finally

delayAdd(4)
  .then((res) => console.log(res))
  .catch((err) => console.error(err))
  .finally(() => console.log("끝"));

const wrap = async () => {
  try {
    const res = await delayAdd(2);
    console.log(res);
  } catch (err) {
    console.error(err);
  } finally {
    console.log("끝");
  }
};

 

반복문에서의 비동기 코드처리

const getMovies = (moviName) => {
  return new Promise((resolve) => {
    fetch(`http://www.omdbapi.com/?apikey=7035c60c&s=${moviName}`)
      .then((res) => res.json())
      .then((res) => resolve(res));
  });
};

const titles = ["frezen", "avengers", "avatar"];

titles.forEach(async (title) => {
  const movies = await getMovies(title);
  console.log(title, movies, "잉");
});

// forEach를 사용하여 await를 진행하면 코드 내부에서는 기다리지만
// 출력은 반복을 하면서 결과값을 반환하기 때문에 배열의 순서대로 나오지 않는다.

// 배열의 순서에 맞게 반환하고싶다면 forEach문이 아닌 for문을 사용

const wrap = async () => {
  for (const title of titles) {
    const movies = await getMovies(title);
    console.log(title, movies);
  }
};

wrap();