JavaScript | async, await

Kate Jung·2022년 3월 22일
0

JavaScript

목록 보기
33/39
post-thumbnail

기본적으로 비동기 코드를 쓰고 Promise를 더 읽기 더 쉽도록 만들어줌.

📌 사용 이유

즉, 가독성 ↑ (Promisethen 메소드를 chain형식으로 호출하는 것보다)

📌 async

🔹 사용법

함수 앞에 async를 붙여주면, Promise 반환
→ 함수 호출 후, then 사용 가능

  • 예시 코드
    async function getName() {
      return "Mike"
    }
    console.log(getName()) // Promise {<fulfilled>: 'Mike'}
    
    getName().then((name)=>{
      console.log(name)
    })
    /* 
    - 콘솔:
    'Mike'
    
    - 설명:
     name이 return되서 'Mike'가 뜸. */

🔹 반환값이 Promise일 경우

값 그대로 사용

async function getName(){
  return Promise.resolve("Tom") // 이 값을 그대로 사용
}
getName().then((name)=>{
  console.log(name) // 'Tom'
})

🔹 함수 내부에서 예외 발생할 경우

rejected 상태의 Promise 반환

  • catch로 확인 가능 (rejected 이기 때문)
    async function getName() {
      throw new Error('error..')
    }
    getName().catch((err)=>{
      console.log(err)
    })
    
    /*
    - 콘솔:
    Error: error..
        at getName (<anonymous>:2:9)
        at <anonymous>:4:1 */

📌 await

🔹 사용법

  • async 함수 내부에서만 사용 가능

    일반 함수에서 사용 시 → 에러 발생.

  • await 오른쪽에는 Promise 가 오고 그 Promise가 처리 될 때까지 기다림.

🔹 예시 코드

function getName(name) {
  return new Promise((resolve, reject)=>{
    setTimeout(()=>{
      resolve(name)
    }, 1000)
  })
}

async function showName(){
  const result = await getName("Mike") // 👈
  console.log(result)
}

console.log("시작")
showName()
/*
- 콘솔:
'시작'
'Mike'

- 설명:
'시작'하고 1초 후에 'Mike'가 찍힘. 
result에 getName에서 resolve된 값을 기다렸다가 넣어줌. */

📌 순차적 적용

1. Promise 코드

const f1 = () => {
  return new Promise((res, rej) => {
    setTimeout(()=>{
      res('1번 주문 완료')
    }, 1000)
  })
};

const f2 = (message) => {
  console.log(message)
  return new Promise((res, rej) => {
    setTimeout(()=>{
      res('2번 주문 완료')
    }, 3000)
  })
}

const f3 = (message) => {
  console.log(message)
  return new Promise((res, rej) => {
    setTimeout(()=>{
      res('3번 주문 완료')
    }, 2000)
  })
}

f1()
	.then(res => f2(res))
	.then(res => f3(res))
	.then(res => console.log(res))
	.catch(console.log)

/*
- 콘솔:
1번 주문 완료
2번 주문 완료
3번 주문 완료 */

2. async, await 적용

(...생략)

console.log('시작');
async function order(){
  const result = await f1() // 👈
  const result2 = await f2(result)
  const result3 = await f3(result2)
  console.log(result3)
  console.log('종료')
}
order()

/*
- 콘솔:
시작
1번 주문 완료
2번 주문 완료
3번 주문 완료
종료 */
  • 동일하게 실행됨.

  • 변수에 데이터가 기다렸다가 들어가는 게 명확히 보임.

    Promise then 보다 가독성 좋음.

    → 대부분의 상황에서 async, await 더 선호

3. rejected 될 경우

  • async, await 함수 → try catch문으로 감싸기
  • Promisecatch 사용

3.1. f2 → rejected로 수정

에러 발생 후, 코드 멈춤

(...생략)

const f2 = (message) => {
  console.log(message)
  return new Promise((res, rej) => {
    setTimeout(()=>{
      rej(new Error('err..')) // 👈 2번을 rejected로 수정
    }, 3000)
  })
}

(...생략)

/*
- 콘솔:
시작
1번 주문 완료
VM248:13 Uncaught (in promise) Error: err..
    at <anonymous>:13:11
    at i (677-07d069a322d4d0596686.js:1:124359) */

3.2. try catch문 사용

  • 에러 로그를 찍고 이후 작업 계속 진행
  • catch 문에서 적절한 에러를 처리해주고 넘어가기
(...생략)

console.log('시작');
async function order() {
  try {           // 👈 try를 시도 하면서 에러가 발생하면
    const result = await f1()
  	const result2 = await f2(result)
  	const result3 = await f3(result2)
  	console.log(result3)
  } catch (e) {   // 👈 catch에서 알 수 있음.
    console.log(e) 
  }
  console.log('종료')
}
order()

/*
- 콘솔:
시작
1번 주문 완료
Error: err..
    at <anonymous>:13:11
    at i (677-07d069a322d4d0596686.js:1:124359)
종료 */ // 👈 작업 계속 진행된 증거

4. Promise.all 사용

async, await 함수 내부에서도 비동기 함수를 병렬로 실행 가능

// f2 → resolve로 수정 후
(...생략)

console.log('시작');
async function order(){
  try {
    const result = await Promise.all([f1(), f2(), f3()]) 
		/* 👆
		- await 한다음에 Promise 옴.
		- Promise.all 로 작성해주고 내부에는 배열로 함수들을 넣어줌. */
  	console.log(result)
  } catch (e) {
    console.log(e)
  }
  console.log('종료')
}
order()

/* 👇 잘 나옴
- 콘솔:
시작
undefined
undefined
(3) ['1번 주문 완료', '2번 주문 완료', '3번 주문 완료']
종료 */

참고

  • 코딩앙마_자바스크립트 중급
profile
복습 목적 블로그 입니다.

0개의 댓글