[Udemy] The Await Keyword

OROSY·2021년 5월 3일
0

TIL

목록 보기
8/18
post-thumbnail

Await

이번에는 저번 글에서 배웠던 Async에 이어 이와 함께 사용하는 Awiat에 대해 살펴봅시다.

자세한 사항은 꼭 MDN 공식문서 - await을 참고해주시기 바랍니다.

1. 코드 예시

const delayedColorChange = (color, delay) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            document.body.style.backgroundColor = color;
            resolve();
        }, delay)
    })
}

위와 같이 배경색을 입력한 delay마다 바꿔주는 함수를 Promise로 구현하였습니다. 위 코드를 async 함수로 호출하는 경우에는 어떻게 할까요?

async function rainbow() {
	return delayeColorChange('red', 1000)
}
rainbow()

위처럼 async 함수 내부에 delayeColorChange('red', 1000)을 통해 Promise 함수 호출을 return합니다. 그러면 async 함수이므로 Promise 객체의 resolve 값을 반환하고 배경색이 바뀌게 됩니다. 그렇다면 이를 여러번 반복하여 시간순서대로 배경색이 바뀌게 하려면 어떻게 하면 될까요?

2. Await

2.1 Await 키워드

이런 경우에 바로 awiat 키워드가 사용됩니다.

async function rainbow() {
    await delayedColorChange('red', 1000)
    return delayedColorChange('orange', 1000)
}
async function rainbow() {
    await delayedColorChange('red', 1000)
    await delayedColorChange('orange', 1000)
    await delayedColorChange('yellow', 1000)
    await delayedColorChange('green', 1000)
    await delayedColorChange('blue', 1000)
    await delayedColorChange('purple', 1000)
}

위와 같이 await 키워드를 활용해 무지개색으로 순서대로 변화하는 코드도 nesting 없이도 쉽게 함수를 연결할 수 있게 되었습니다.

async 함수에는 await식이 포함될 수 있습니다. 이 식은 async 함수의 실행을 일시 중지하고 전달된 Promise의 해결을 기다린 다음 async 함수의 실행을 다시 시작하고 완료 후 값을 반환합니다.

2.2 then 속성

async 함수를 호출 시, then 속성을 덧붙일 수도 있습니다.

async function rainbow() {
    await delayedColorChange('red', 1000)
    await delayedColorChange('orange', 1000)
    await delayedColorChange('yellow', 1000)
    await delayedColorChange('green', 1000)
    await delayedColorChange('blue', 1000)
    await delayedColorChange('violet', 1000)
    return console.log("ALL DONE!")
}
rainbow().then(() => { console.log('END OF RAINBOW!') })

위에서 호출한 rainbowthen속성을 붙이면, 배경색이 모두 바뀌고 ALL DONE!이 콘솔에 출력된다음 then 속성에 콜백 함수로 정의한 END OF RAINBOW!가 콘솔에 출력됩니다.

2.3 async 함수 안에 또 async 함수를?

그렇다면, async 함수 내부에 async 함수를 호출할 수 있을까요?

async function printRainbow() {
    await rainbow() // Promise가 resolve 될 때까지 기다림
    console.log('END OF RAINBOW!')
}
printRainbow()

위 함수처럼 가능하며, await 키워드도 활용이 가능합니다. then 속성으로 구현한 코드와 동일하게 실행됩니다.

3. try, catch

하지만 아직까지 async 함수를 통해 Promiserejected의 경우, 어떻게 해결해야하는지 알지 못했습니다.

try {
    asdfsaf.log('asdf') // ReferenceError
} catch (e) {
    console.log('ITS OK!!', e) // try 무시한 후 catch 실행! e는 에러 내용 출력
}

여기서 try, catch가 사용됩니다. 위에서 보이는 것처럼 try는 값에 에러가 들어간다하더라도 뒤에 이어지는 catch에서 이를 무시하고 실행하게 됩니다. 또한, catch의 매개변수는 try의 에러 내용을 출력합니다.

4. fakeRequest

const fakeRequest = (url) => {
    return new Promise((resolve, reject) => {
        const delay = Math.floor(Math.random() * (4500)) + 500;
        setTimeout(() => {
            if (delay > 4000) {
                reject('Connection Timeout :(')
            } else {
                resolve(`Here is your fake data from ${url}`)
            }
        }, delay)
    })
}

이전 시간에 만들었던 fakeRequest 코드를 통해 try, catch를 활용해봅시다.

async function makeTwoRequest() {
    try {
        let data1 = await fakeRequest('/page1')
        let data1 = await fakeRequest('/page2')
        console.log(data1)
    } catch (e) {
        console.log('CAUGHT AN ERROR!')
        console.log('error is:', e)
    }
}

async 함수로 호출을 했습니다. 에러가 발생했다면, 실제로 에러가 발생하고 이후에 내용은 실행되지 않습니다. 하지만 아래에서 보여드리는 내용처럼 에러가 발생하고 난 후에 catch의 내용이 실행된 것을 확인할 수 있습니다.

profile
Life is a matter of a direction not a speed.

0개의 댓글