티스토리 뷰

728x90
반응형

비동기 처리는 함수를 호출하고 실행결과가 반환이 될 때까지 다른 작업을 진행하다가, 처리가 완료되었다는 이벤트를 수신하였을 때 작업을 마저 처리하는 방식입니다. Promise, Async를 이용하면 비동기 처리 로직을 쉽게 작성할 수 있습니다. Await를 사용하면 비동기 처리 API를 동기식 처리로 전환 가능하여, 로직의 실행 순서를 제어할 수 있습니다. 이번 포스팅에서는 Node.js에서 Promise, Await, Async를 이용하여 비동기식, 동기식 코드를 작성하는 방법에 대해 알아보겠습니다. Node.js에서 동기, 비동기 처리 원리에 대해 궁금하신분은 아래 포스팅 참고바랍니다.

 

[Node.js] 비동기 처리 로직의 실행 원리 분석

Node.js 또는 자바스크립트는 동기식, 비동기식으로 동작하는 API를 지원합니다. 절차 지향, 객체 지향 프로그래밍 언어인 C/C++, Java로 애플리케이션을 개발한 사람은 비동기식으로 동작하는 API를

it-techtree.tistory.com

Promise로 비동기 처리 로직 작성하기

Promise는 자바 스크립트에서 비동기 처리 로직을 다루기 위한 객체입니다. Promise 객체를 생성할 때, Callback함수를 인자로 작성합니다. 일반적으로, callback 함수에 비동기 처리 API를 호출하는 코드를 작성합니다. 콜백 함수의 파라미터로 resolve와 reject가 주어집니다. callback 함수가 성공적으로 수행되면 resolve()를 호출하고, callback 함수의 실행이 실패되었다면 reject()를 호출합니다.  Promise함수 작성 및 호출하는 코드는 아래와 같이 작성합니다.

function promiseTest() { 
    return new Promise((resolve, reject) => {
        try{
            // 함수 작성
            setTimeout(() => { resolve('Success') },1000)           
        } catch (err) {
            reject('Fail') // 또는 throw new Error('error')
        }
    })
}

function main() {
	promiseTest().then(data => {
        console.log(data)
    }).catch(err => {
        console.log('ERROR : ' + err)
    })
    console.log('End')
}

main()

Promise 함수 실행결과

소스코드를 실행한 결과, 프로미스에서 resolve를 호출하면, then()이 실행됩니다. 만약, 프로미스에서 reject가 호출되면, catch가 실행됩니다. 프로미스 함수 내부에서 Exception이 발생해도 catch 블록이 실행됩니다. promiseTest 함수가 호출되면, 프로미스 내부에 비동기 처리 API인 setTimeout를 실행합니다. setTimeout는 실행만 하고 promiseTest함수를 빠져나와, 계속 스크립트 실행을 이어나갑니다. 'End'가 출력된 후, 1초 뒤 timeout에 정의한 콜백 함수에서 resolve가 호출되어 then함수 내부의 console.log함수가 실행되어 'Success'를 출력되고, 프로그램은 종료됩니다.

비동기 처리는 성능 관점에서는 효율이 좋지만, 소스코드를 이해하고 유지 보수하는 개발자 입장에서는 가독성이 좋지 않습니다. async, await는 비동기 처리 로직을 쉽게 작성할 수 있을 뿐만 아니라, 비동기 처리를 동기식 처리 로직으로 변환할 수 있습니다. 다음으로, async와 await에 대해 알아보겠습니다.

async, await으로 Promise를 동기식 처리로 작성하기 

앞에서 구현한 비동기 처리 로직을 동기식으로 변경하는 방법이 있습니다. 예전에는 콜백 함수 안에 콜백 함수를 계속 구현하여, 비동기 처리 로직을 동기식으로 변환하였는데, 이러한 코드 작성 패턴으로 인해 콜백 지옥을 경험하는 경우가 많았습니다. 하지만, await과 async를 사용하면, 비동기 처리 로직을 동기식 처리로 변경 가능합니다.

await은 Promise가 종료될 때까지 대기하도록 지시하는 키워드입니다. async는 함수가 항상 프로미스로 반환되도록 지시하는 키워드입니다. async function의 반환 값은 명시하지 않아도 항상 Promise.resolve()로 치환되어 값이 반환됩니다. 궁금하시다면, async function의 반환 값을 출력해보면 Promise 객체가 출력되는 것을 확인할 수 있습니다. 다시 돌아와서, 앞에서 구현한 promiseTest함수를 await과 async 키워드를 이용하여, 동기식 처리로 변경해보겠습니다.

function promiseTest() { 
    return new Promise((resolve,reject) => {
        setTimeout(() => {
            console.log('Success')
            resolve()
        },1000)
    })
}


async function main() {
    try {
        await promiseTest()
        console.log('End')
    } catch(err) {
        console.log('ERROR : ' + err.message)
    }   
}

main()

기존에 작성한 코드와 다른 점은 promiseTest함수를 호출할 때 await가 추가되었고, main함수 정의에 async가 추가된 것입니다. await은 async function 내에서만 사용할 수 있는 키워드입니다. 만약, 일반 함수에서 await를 사용하면 아래와 같은 오류가 출력됩니다.

SyntaxError: await is only valid in async functions and the top level bodies of modules

main함수를 실행하면, promiseTest 함수에서 호출된 setTimeout이 종료될 때까지 기다린 후 프로미스가 종료되면 'End'가 출력됩니다.

async function내부에 try-catch 구문을 사용하였는데, 이는 promise의 then, catch를 사용한 것과 동일한 코드 작성 패턴입니다. await을 사용하여 then의 동작을 구현하고, catch는 동일하게 Exception을 잡는 역할을 합니다. 프로미스를 활용하여 비동기 처리를 개선하고자 하시는 분은 아래 포스팅도 함께 참고부탁드립니다.

 

[Node.js] Promise.all을 활용한 비동기 코드 작성법

Promise(=프로미스)는 자바스크립트 언어에서 사용되는 비동기 처리 객체입니다. Promise는 then, catch, async, await, try-catch 구문과 조합하여 동기, 비동기, 동기 처리 로직을 구성합니다. 앞에 언급한 키

shcheon.tistory.com

지금까지 Promise, Async, Await을 이용하여 비동기, 동기 처리 로직을 작성하는 방법에 대해 알아보았습니다.

728x90
반응형
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함