[JavaScript] async와 await

Dodam·2023년 9월 10일
1

[JavaScript]

목록 보기
9/10
post-thumbnail

async & await

async 와 await 은 가장 최근에 나온 비동기 처리 패턴으로, 기존의 콜백함수와 프로미스의 단점을 보완한 문법이다.

흔히 말하는 콜백지옥 혹은 여러 개의 프로미스가 서로 의존하고 있는 경우, 코드의 가독성이 저하될 수 있다.
이를 async와 await를 사용하여 더욱 간편하게 가독성있는 코드를 작성할 수 있다.

사용법

  • 함수 앞에 async를 붙이면 해당 함수는 자동으로 프로미스를 반환하게 된다.
  • 비동기로 처리되는 부분에 await를 붙이면 해당 프로미스가 끝날 때까지 기다린다. (동기적으로 처리)
  • await은 async가 붙은 함수 안에서만 사용 가능하다.

다음과 같이 프로미스로 작성한 코드를 async를 사용해 간편하게 바꿀 수 있다.
async 함수에서 returnresolve()와 같은 역할을 한다.
문자열을 반환하는 것처럼 보이지만 실제로는 프로미스를 반환한다.

function promiseFunc() {
    return new Promise((resolve, reject) => {
        resolve('Promise is awesome')
    })
}

promiseFunc().then(console.log)

async function asyncFunc() {
    return 'Async is awesome'
}

  asyncFunc().then(console.log)

프로미스에서 동기적으로 처리하기 위해 후속 처리 메소드인 then() 메소드를 사용해 동기적으로 처리했다면,
이제는 프로미스를 반환하는 함수 앞에 await을 붙여 더 간편하게 동기적으로 처리할 수 있다.

또한 프로미스를 사용해 동기적으로 처리하는 경우, fullfilled 값을 then() 후속 처리 메소드를 통해 결괏값을 인자로 넘겨 체인 내에서 처리해야 하지만
await을 사용하면 fullfilled 값을 외부로 넘겨줄 수 있다.


다음과 같은 프로미스로 작성한 코드를 async와 await을 사용하여 동기적으로 처리할 수 있다.

const timeout = (value, timeout) => new Promise((resolve, reject) => {
	setTimeout(() => resolve(value), timeout)
})

timeout('Hello ', 1000)	 // 프로그램 실행 후 1초 뒤에 수행
	.then(result => {
		console.log('complete promise')
		return timeout(result + 'My name is ', 2000)  // 프로그램 실행 후 3초 뒤에 수행 (1 + 2)
	}).then(result => {
		console.log('complete promise')
		return timeout(result + 'hyun ', 3000)  // 프로그램 실행 후 6초 뒤에 수행 (1 + 2 + 3)
	}).then(result => {
		console.log('complete promise')
		console.log(result)
	})
complete promise
complete promise
complete promise
Hello My name is hyun

const timeout = (value, timeout) => new Promise((resolve, reject) => {
    setTimeout(() => resolve(value), timeout)
})

async function awaitFunc() {
    let str = ''

    str += await timeout('Hello ', 1000)  // 프로그램 실행 후 1초 뒤에 수행
    console.log('complete promise')
    str += await timeout('My name is ', 2000)  // 프로그램 실행 후 3초 뒤에 수행 (1 + 2)
    console.log('complete promise')
    str += await timeout('hyun ', 3000)  // 프로그램 실행 후 6초 뒤에 수행 (1 + 2 + 3)
    console.log('complete promise')

    return str
}

awaitFunc().then(console.log)
complete promise
complete promise
complete promise
Hello My name is hyun

예외 처리

프로미스에서 예외 처리를 할 때, 후속 처리 메소드인 catch() 메소드를 사용하여 예외 처리를 한다.
async와 await을 사용하면 프로미스를 함수 내부에서 동기적으로 처리할 수 있기 때문에 try-catch 구문을 사용하여 예외 처리를 할 수 있다.

물론 모든 예외를 try-catch 구문으로 처리하는 것은 아니다.
await은 async가 붙은 함수 내에서만 사용 가능하기 때문에, 최종 결과나 처리되지 못한 에러의 경우 catch() 메서드를 사용해 처리해준다.

catch() 메소드를 사용한 예외 처리 방법

async function promise() {
	throw 'error';
}

promise()
	.then(result => console.log('status : fulfilled,', result))
	.catch(error => console.log('status : rejected,', error))
status : rejected, error

try-catch 구문을 이용한 예외 처리 방법

함수 내부에서 예외가 발생한 경우 try-catch 구문을 이용하여 예외를 처리할 수 있다.

async function promise() {
	throw 'rejected';
}

async function exceptionFunc() {
	try {
    	await promise()
    } catch (e) {
    	console.log('catch error!', e)  
    }
}

exceptionFunc()
catch error! rejected

catch() 메소드와 try-catch 메소드를 혼용한 예외 처리 방법

함수 내부에서 예외가 발생하였지만 예외를 내부가 아닌 외부로 넘겨 처리하고 싶은 경우 다음과 같이 혼용하여 사용할 수 있다.

async function promise() {
	throw 'rejected';
}

async function exceptionFunc() {
	try {
    	return await promise()
    } catch (e) {
    	console.log('catch error!', e)
      	throw e
    }
}

exceptionFunc()
	.then(result => console.log('status : fulfilled,', result))
	.catch(error => console.log('status : rejected,', error))
catch error! rejected
status : rejected, rejected
profile
Good things take time

0개의 댓글