'return await promise' vs 'return promise'

“return await promise” vs “return promise”

아래 두 함수를 보자.

async function func1() {
    const promise = asyncOperation();
    return await promise
}


async function func2() {
    const promise = asyncOperation();
    return promise
}

두 함수는 return옆의 await말고는 아무런 차이가 없다.

그러나 두 함수가 동작하는 방식의 차이를 아는 것은 중요하다.

아래 함수를 사용해서 두 함수를 테스트해보자.

function promisedDivision(n1: number, n2: number) {
    if (n2 === 0) {
        return Promise.reject(new Error('Cannot divide by 0'));
    } else {
        return Promise.resolve(n1 / n2);
    }
}

async function divideWithAwait() {
    return await promisedDivision(6, 2)
}


async function main() {
    const result = await divideWithAwait();
    console.log(result)
}

위의 main()함수를 실행하면 어떻게 될까?

divideWithAwait()에서도, main()에서도 await를 걸어주었기 때문에 당연히 3이 출력되는 것을 볼 수 있다.

이제 await를 빼고 테스트해보자.

function promisedDivision(n1: number, n2: number) {
    if (n2 === 0) {
        return Promise.reject(new Error('Cannot divide by 0'));
    } else {
        return Promise.resolve(n1 / n2);
    }
}

async function divideWithAwait() {
    return promisedDivision(6, 2)
}


async function main() {
    const result = await divideWithAwait();
    console.log(result)
}

return await에서 return으로 바뀌었지만, 여전히 return값은 3이 나온다.

이 단계에서는 return awaitreturn이 다르게 작동하지 않는다.

다르게 행동하는 케이스를 살펴보자.

function promisedDivision(n1: number, n2: number) {
    if (n2 === 0) {
        return Promise.reject(new Error('Cannot divide by 0'));
    } else {
        return Promise.resolve(n1 / n2);
    }
}

async function divideWithAwait() {
    try {
        return await promisedDivision(5, 0)
    } catch (e) {
        console.log(e) // logs Error('Cannot divide by 0')
    }
}


async function main() {
    const result = await divideWithAwait();
    console.log(result)
}

이번에는 divideWithAwait()함수에 try-catch구문을 추가했다.

마찬가지로 return await promise의 케이스를 먼저 테스트해보면 catch에서 걸려서 에러가 찍히는 것을 확인할 수 있다.

function promisedDivision(n1: number, n2: number) {
    if (n2 === 0) {
        return Promise.reject(new Error('Cannot divide by 0'));
    } else {
        return Promise.resolve(n1 / n2);
    }
}

async function divideWithAwait() {
    try {
        return promisedDivision(5, 0)
    } catch (e) {
        // Rejection NOT caught
        console.log(e)
    }
}


async function main() {
    const result = await divideWithAwait();
    console.log(result)
}

main().catch((e) => console.log("Uncaught", e))

return의 케이스는 어떨까? 에러가 catch에서 잡히지 않는다.

맨 밑의 Uncaught를 임시로 만들어 두었는데, 중요한 것은 reject된 promise 객체를 그대로 뱉었다는 것이다.

이를 이용해서, return promisereturn await promise의 사용처를 명백히 정할 수 있을 것이다.

에러가 발생했을 때, 리턴하는 함수(divideWithAwait) 내에서 처리를 할 로직이 있다면 return await를 사용하고, 밖에서(main) 처리되기를 원한다면 return을 사용하면 될 것이다.

Last updated