만자의 개발일지

[JavaScript] async와 await 본문

JavaScript

[JavaScript] async와 await

박만자 2022. 4. 12. 00:09

async&await

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

 

흔히 말하는 콜백지옥 혹은 여러개의 프로미스가 서로 의존하고있는 경우 코드의 가독성이 저하될 수 있습니다.

이를 asyncawait를 사용하여 더욱 간편하게 가독성있는 코드를 작성할 수 있습니다.

 

 

사용법

asyncawait의 사용법은 매우 간단합니다.

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

 

다음과 같이 프로미스로 작성한 코드를 async를 사용해 간편하게 사용할 수 있습니다.

async 함수에서 returnresolve()와 같은 역할을 합니다.

문자열을 반환하는 것처럼 보이지만 실제로는 프로미스를 반환합니다.

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

promiseFunc().then(console.log)
Promise is awesome

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

asyncFunc().then(console.log)
Async is awesome

 

프로미스에서 동기적으로 처리하기 위에 후속 처리 메소드인 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 + 'manja ', 3000)       // 프로그램 실행후 6초뒤에 수행됨(1 + 2 + 3)
	}).then(result => {
		console.log('complete promise')
		console.log(result)
	})
complete promise
complete promise
complete promise
Hello My name is manja

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('manja ', 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 manja

 

예외 처리

프로미스에서 예외처리를 할 때 후속 처리 메소드인 catch() 메소드를 사용하여 예외처리를 하였습니다.

이제 asyncawait을 사용하면 프로미스를 함수 내부에서 동기적으로 처리할 수 있기 때문에 try-catch 구문을 사용 예외 처리를 할 수 있습니다.

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

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

 

참고

Comments