[DAY 16] VanillaJS를 통한 자바스크립트 기본 역량 강화 I (5)

송히·2023년 10월 10일
post-thumbnail

Today I Learn📖

  • Promise (강의)
  • async, await (강의)
  • fetch (강의)

Promise

  • Promise: 비동기 작업을 제어하기 위해 나온 개념
    -> Promise로 정의된 작업끼리는 체이닝으로 연결할 수 있기 때문에 depth가 1단계만 필요 (콜백헬 탈출~)
    • then으로 비동기 작업 이후 실행할 작업 지정 (체이닝으로 여러 개 연결 가능)
    • catch로 에러 잡을 수 있음 (안 넣으면 에러 발생시 체인이 멈춤, 주로 체이닝 끝에 씀)
    • finally로 성공/실패 여부와 상관 없이 호출해야 할 코드를 처리할 수 있음
function asyncPromiseWork() {
  // 작업 코드~
  return new Promise((resolve, reject) => {
	//promise 내부에서 비동기 상황이 종료될 때, resolve 함수 호출
    //promise 내부에서 오류 상황일 때, 실행 종료되고 reject 함수 호출
    	return resolve("complete")
  })
}

// then의 result = resolve의 return 값인 complete
asyncPromiseWork().then(result => { return Promise_2_Work(result) })
  				  .then(result => { return Promise_3_Work(result) })
  				  .catch(e => console.log("에러"))
				  .finally(() => console.log("항상 실행됨"))

Promise 내장 함수들

  • Promise.all([배열 안에 실행시킬 Promise 함수들 , 로 나열]).then(나열된 Promise 다 끝나면(가장 마지막 거 끝나면) 실행)~: 여러 Promise 동시 처리 (클라이언트에서 의존성 없는 API 여러 개 호출 시 유용)

  • Promise.race(iterable).then(): 여러 promise중 하나라도 resolve / reject 되면 종료
    -> 아예 끝나는 건 아니고 그 이후로도 promise 끝나는 순서대로 then 실행됨

  • Promise.any(iterable): 여러 promise중 하나라도 resolve되면 종료
    -> Promise.race와 비슷하지만, 앞에 reject 된 거 있어도 그건 무시하고 그 뒤로 처음 resolve된 것만 인정함

  • Promise.allSettled(iterable): 여러 promise들이 성공/실패에 상관없이 모두 이행된 경우 처리됨

  • Promise.resolve: 주어진 값으로 이행하는 Promise.then 객체 생성 (주어진 값이 Promise인 경우 해당 Promise 반환(성공 상태))
    => return 타입을 promise로 맞추는 것

  • Promise.reject: 주어진 값으로 reject 처리된 Promise.then 객체 생성, romise.resolve와 반대 개념 (주어진 값이 Promise인 경우 해당 Promise 반환(실패 상태))



async, await

  • 비동기 작업을 제어하는 역할 => 하지만 동기 코드처럼 보여 가독성 올라감
// promise로 작성한 코드
const delay = (delayTime) => {
  return new Promise(resolve => setTimeout(resolve, delayTime))
}

const work = () => {
  console.log("work run");
  delay(1000)
    .then(() => {
      console.log("work 1 complete.");
      return delay(1000);
    })
    .then(() => {
      console.log("work 2 complete.");
      return delay(1000);
    })
    .then(() => {
      console.log("work 3 complete.");
      return delay(1000);
    })
    .then(() => {
      console.log("work all complete!");
    });

  console.log("work running..");
};

work();
// async & await로 작성한 코드 -> 가독성 올라감, depth도 없음
const work = async () => {
  console.log("work run");
  await delay(1000);
  console.log("work 1 complete.");

  await delay(1000);
  console.log("work 2 complete.");

  await delay(1000);
  console.log("work 3 complete.");

  await delay(1000);
  console.log("work all complete!");
};

work();
  • async 키워드가 붙은 함수는 실행 결과가 Promise로 감싸짐
async function asyncRun() {
  return "hello";
}

console.log(asyncRun); // Promise {<fullfilled>: "hello"}

-> 결과가 Promise 형태니까 다음 할 일 지정해주는 then 이용
asyncRun.then((message) => console.log(message)) // hello
  • try & catch로 에러 잡기
try {
  // await인 비동기 함수
  ex) 로딩중 보여주기
} catch {
  // Promise의 .catch와 비슷한 역할 -> 에러 잡기
} finally {
  // Promise의 .finally와 비슷한 역할 -> 무조건 실행
  ex) 로딩중 숨기기
}


fetch

  • 비동기 http 요청을 좀 더 쓰기 편하게 해주는 API
    => XMLHTTPRequest대체할 수 있고, Promise 기반으로 동작함
fetch("https://원하는API주소")
  .then(res => {
	return res.json() // response의 응답을(body를) .json / text 등으로 바꿔줘야함 (안 그러면 객체 전체를 다 보여주니까...)
  })
  .then(data => {
	console.log (data) // 드디어 원하는 데이터 볼 수 있음
  })

blob: 이미지 파일을 응답으로 받을 때 사용하는 형식
ex) blob으로 받아온 데이터를 URL.createObjectURL(data)로 넣으면 파일의 url 얻을 수 있음
-> 그 url을 body에 append하면 사진으로도 볼 수 있음

  • fetch는 HTTP error가 발생하더라도 reject 되지 않음 ( ex) 404, ...)
    (네트워크 에러나 요청이 완료되지 못한 경우에만 reject 됨)
    => 서버 요청 중 에러가 생겼을 경우에도 에러 발생 없이 then으로 떨어지므로, response의 status code나 ok를 체크해줘야함 (체크 없이 catch만 쓰면 안 됨)
fetch("존재하지 않는 API") // 404 에러
  .then(res => {
	if (res.ok) { // 응답이 ok여야 통과됨 (status가 200~299 사이인 경우만 true됨)
     			  // -> 서버 오류가 아닌 300대들은 다른 방법 사용 필요
      return res.json()
    }
    throw new Error("요청을 처리하지 못하였어요.") // 아니면 오류 뱉음
  })
  .then (data => {
	console.log (data)
  })
  .catch(e => {
	document.querySelector('body').innerHTML = e.message
})
  • fetch는 2번째 인자로 옵션을 줄 수 있음


😊오늘의 느낀점😊

async, await를 사용하면 확실히 가독성이 올라감을 느꼈다.
그리고 솔직히 fetch를 사용하기 전인 지난 강의에서는 api 불러오는 코드가 너무 복잡해서 사용할 자신이 없었는데, fetch를 이용하면 api 호출이 간편한 것 같다.
다만 응답을 잘 확인해야하는 걸 꼭 기억해야할 것 같다.

profile
데브코스 프론트엔드 5기

0개의 댓글