본문 바로가기
CodeIt_Sprint/비동기_자바스크립트

(4)비동기_자바스크립트_API 불러오기 작업의 오류처리 => try,catch,finally문, 비동기함수 작성 then()문법 ,then()+try,catch,finally문, 작동원리

by 코잼민 2024. 12. 3.

● 이론0_ API 데이터 불러오고, 처리하는 코드 작성 시, 오류를 생각안했다.

export async function getIntervers() {

  const strData = await fetch('https://learn.codeit.kr/api/interview-results');

  const jsonData = await strData.json();

  console.log(jsonData);

}

◇ 오류 요인

  • fetch 하려고 하는 url이 잘못 기재
  • url 내 데이터가 없다.
  • ..등등

● 이론1_ try{}Catch{}finally{} 문

○ 정의 :

  • try {..} : 비동기 작업과 최종 결과가 구현될 블록 , 중간에 오류가 날 시, catch 블록으로 이동
  • catch {..} : try{}에서 넘어올 경우, 오류가 날 경우 작동할 것들을 구현할 코드 블록
  • finally {..} : try{..} 부분이 완료된 후 || catch{..} 부분이 완료된 후, 넘어올 코드 부분 //즉 오류가 나든 안나든 시행해야할 코드 블록

○ 예시 코드 : 위의 코드를 try {} catch {} finally {} 문으로 코드 작성

export async function getIntervers() {

  try {

    const strData = await fetch('https://learn.codeit.kr/api/interview-results');

    const jsonData = await strData.json();

    console.log(jsonData);
  }
  catch (error) {//이 error 객체는 정확히 뭔지는 아직 안 배움
    console.log('ERROR');
    return; //▲catch문에 return;을 밖아도, finally{} 무조건 실행됨
  }
  finally {
    console.log('Finished');
  }
}

○ 예시 코드 하나더 :

export async function getMenus() {
  try {
    const response = await fetch('https://learnnnnn.codeit.kr/api/menus');
    const menus = await response.json();
    return menus;
  } catch (error) {
    console.log('데이터를 가져오지 못했습니다 :(');
    return null;
  } finally {
    console.log('getMenus() 함수가 끝났습니다.');
  }
}

● 이론2_ try{..} catch(error){..} finally{..} 의 정확한 동작 순서 원리

//function.js

export async function printMenus() {
  try {
    const response = await fetch('https://learnnnnn.codeit.kr/api/menus');
    const menus = await response.json();
	console.log(menus);	
  } catch (error) {
    console.log('데이터를 가져오지 못했습니다 :(');
    return null;
  } finally {
    console.log('getMenus() 함수가 끝났습니다.');
  }
}

//main.js
import { getMenus } from './function.js';

printMenus();//비동기 작업1

console.log('Task2');//동기 작업1

console.log('Task3');//동기 작업2

○ 동작 순서 :

  • 순서1_ 비동기 작업에서, Promise에 반응 주고, 상태확인
//function.js
const response = await fetch('https://learnnnnn.codeit.kr/api/menus');//Promise 객체 건들임
  • 순서2_ 그 동안, 동기 작업 1,2 실행
//function.js
const response = await fetch('https://learnnnnn.codeit.kr/api/menus');//Promise 객체 건들임
  • 순서3_ 건들여놨던, Promise 객체 상태 Error 발생 => 컴파일러는 main.js에서 다시 function.js의 promise 으로 돌아감, => error를 들고 컴파일러는 catch문으로 이동, 전달
//function.js

try {
    const response = await fetch('https://learnnnnn.codeit.kr/api/menus');//1_ Promise 객체 Rejected 확인하고, 들고
    const menus = await response.json();
console.log(menus);
  } catch (error) {//2_ catch문에 전달
    console.log('데이터를 가져오지 못했습니다 :(');
    return null;
  }
  • 순서4_ return;이 있어도 finally문으로 이동해서, 작동
//function.js

  finally {
    console.log('getMenus() 함수가 끝났습니다.');
  }

● 이론3_then() 메소드 기본 문법 

○ 이론0의 코드를 then메소드로 구현해보기 :

//await 문법으로 구현한 비동기 함수
export async function getIntervers() {

  const strData = await fetch('https://learn.codeit.kr/api/interview-results');

  const jsonData = await strData.json();

  console.log(jsonData);

}

//fetch + then() 문법으로 구현한 비동기 함수
async function PrintIntervers()
{
	fetch('https://learn.codeit.kr/api/interview-results')
    	.then((strData)=>strData.json())
      .then((jsonData)=>console.log(jsonData));
}

PrintIntervers();

fetch ~.then()은 한 문장마다 ";"가 아닌 마지막에만 ";"를 붙인다는 점 기억

동작 원리

◎ 연습문제 :

실습 설명

function getRandomElement(arr) {
  const randomIdx = Math.floor(Math.random() * arr.length);
  return arr[randomIdx];
}

console.log('메뉴 고르는 중...');

// const response = await fetch('https://learn.codeit.kr/api/menus');
// const menus = await response.json();
// const randomMenu = getRandomElement(menus);
// console.log(`오늘의 랜덤 메뉴는 ${randomMenu.name}입니다!`);

main.js 파일에는 점심 메뉴를 랜덤으로 골라 주는 코드가 있습니다. 코멘트 처리된 부분을 .then() 메소드를 사용하도록 바꿔 보세요.

실습 결과

메뉴 고르는 중...
오늘의 랜덤 메뉴는 삼계탕입니다!

- 답 :

function getRandomElement(arr) {
  const randomIdx = Math.floor(Math.random() * arr.length);
  return arr[randomIdx];
}

console.log('메뉴 고르는 중...');

fetch('https://learn.codeit.kr/api/menus')
  .then((response) => response.json())
  .then((menus) => {
    const randomMenu = getRandomElement(menus);
    console.log(`오늘의 랜덤 메뉴는 ${randomMenu.name}입니다!`);
  });

● 이론4_then()문법에서 try , catch, finally() 문 추가 적용 문법

○ await문법의 try,catch,finally문

export async function getIntervers() {

  try {

    const strData = await fetch('https://learn.codeit.kr/api/interview-results');

    const jsonData = await strData.json();

    console.log(jsonData);
  }
  catch (error) {//이 error 객체는 정확히 뭔지는 아직 안 배움
    console.log('ERROR');
    return; //▲catch문에 return;을 밖아도, finally{} 무조건 실행됨
  }
  finally {
    console.log('Finished');
  }
}

○ then()문법의 try,catch,finally문 작성하기

async function printInterviewers_2() {
  fetch('https://learn.codeit.kr/api/interview-results')
    .then((strData) => strData.json())
    .then((jsonData) => console.log(jsonData))
    .catch((error) => console.log('Error'))
    .finally(() => console.log('Finished'));
}

○ ★then() + try.catch,finally문의 동작원리 

  • 알아야 할 개념 :

▶ 각 fetch(), then() , catch(), finally() 반환값 : 각각의 Promise 객체

각 메소드는 위의 Promise 반환값의 상태에 따라 다르게 작동된다.

- 위의 메소드의 반환값 상태 : fulfilled 상태일 경우, => 자기 자신의 메소드의 CallBack 함수 작동 시작

- 위의 메소드의 반환값 상태 : rejected 상태일 경우,

=> CallBack 호출 X ,

=> Catch()의 CallBack 함수 작동 시작

=>반환값은 return에 따라 다름 (console.log('Error')일 경우, undefined 반환) => catch()의 Promise는 fullfied 상태이다.

▶ finally는 무조건 반환값이 fulfilled 상태의 promise 이다.

 

fetch부터 rejected promise 반환할 경우

◎ 연습문제2 :

실습 설명

main.js 파일에 오류를 처리하는 코드를 추가해 주세요.

  • ● 만약 오류가 발생하면 프로그램이 고장났습니다 :(라는 메시지를 출력하세요.
  • 프로그램이 끝나기 전에 프로그램이 끝났습니다.라는 메시지를 출력하세요.

코드를 실행하면 아래와 같은 결과가 출력돼야 합니다.

실습 결과

프로그램이 고장났습니다 :(
프로그램이 끝났습니다.

 

- 답 :

function getRandomElement(arr) {
  const randomIdx = Math.floor(Math.random() * arr.length);
  return arr[randomIdx];
}

fetch('https://learnnnnn.codeit.kr/api/menus')
  .then((response) => response.json())
  .then((menus) => {
    const randomMenu = getRandomElement(menus);
    console.log(`오늘의 랜덤 메뉴는 ${randomMenu.name}입니다!`);
  })
  .catch((error)=>{
    console.log('프로그램이 고장났습니다 :(');
  })
  .finally(()=>{
    console.log('프로그램이 끝났습니다.');
  });
  // 여기에 코드를 작성하세요.