본문 바로가기
프로그래밍 언어/Javascript

자바스크립트 비동기, Promise, async, await

by pagehit 2021. 8. 17.
반응형

웹 브라우저에서 동작하는 자바스크립트 프로그램은 어떤 동작을 하기 전에 사용자의 클릭을 기다리는 이벤트를 중심으로(event-driven) 동작한다. 네트워크를 통해 데이터를 전달 받거나 클릭과 같은 어떤 이벤트가 발생하기 전에 프로그램은 계산 과정을 멈추는 비동기(asynchronous)적으로 동작할 필요가 있다. 

 

프로미스(Promise)는 ES6에서 도입되었으며, 비동기 연산의 미래의 결과를 나타내는 객체이다.(결과를 바로 사용할 수도 있고, 사용하지 못할 수 도 있다)

async와 await은 ES2017에서 도입되었으며, Promise로 비동기를 구현하는 코드를 마치 동기(synchronous) 프로그램을 작성하는 것처럼 간단히 비동기 프로그램을 작성할 수 있도록 만들어 준다. 

asynchronous iterator와 for/await 루프는 ES2018에서 도입되었으며, 동기적으로 동작하는 것처럼 보이는 간단한 반복문을 작성해 비동기 이벤트 스트림을 처리할 수 있다.

 

콜백함수(다른 함수에 전달하는 함수) 기반으로 비동기 프로그램을 작성하면 콜백함수 안에서 콜백함수를 호출하고 그 안에서 또 콜백함수를 호출하는 지옥에 빠질 수 있다. Promise는 이 중첩된 콜백함수를 Promise chain을 이용해 선형으로 쉽게 표현해 준다. 또한, 콜백함수를 사용하면 예외처리가 이전의 콜백함수를 따라 역으로 전달되기 어려운데 Promise는 chain을 따라 에러를 전달하는 방법을 제공한다.

 

Promise는 여러번 반복해서 사용할 수 없다. 따라서 load 이벤트 핸들러(이벤트 콜백 함수)로 사용할 수 있지만, 여러번 클릭되는 버튼의 클릭 이벤트 핸드러로는 사용될 수 없다.

 

getJSON("/api/user/profile").then(displayUserProfile).catch(handleProfileError);

 

위 코드에서 getJSON()과 같은 어떤 함수가 비동기 연산을 수행하고 Promise 객체를 반환한다. Promise 객체는 then() 매소드를 통해 콜백함수를 등록하며 이때 이 콜백함수도 비동기적으로 호출된다. getJSON() 함수 또는 then() 매소드에 등록된 콜백함수에서 에러가 발생하면 catch() 매소드에 등록된 에러 핸들러가 호출된다.

getJSON() 함수가 동작하고 then() 매소드에 등록된 콜백함수가 호출되면 Promise 객체가 fulfilled 상태라고 말하며('약속이 이행되었다'), 에러가 발생하여 에러 핸들러가 호출되면 rejected 상태라고 한다('약속이 거부되었다'). 이 두 상태를 합쳐 Promise 객체가 settled 상태라고 말한다.

 

fetch(documentURL)                      // Make an HTTP request
    .then(response => response.json())  // Ask for the JSON body of the response
    .then(document => {                 // When we get the parsed JSON
        return render(document);        // display the document to the user
    })
    .then(rendered => {                 // When we get the rendered document
        cacheInDatabase(rendered);      // cache it in the local database.
    })
    .catch(error => handle(error));     // Handle any errors that occur

 

위 처럼 Promise chain을 이용할 수 있다.

보통 매소드 체인을 구현할 때 하나의 객체만 존재하도록 구현한다. 즉 객체의 매소드는 자신의 객체를 반환하도록 구현한다. 하지만 Promise의 then()은 새로운 Promise 객체를 반환한다.

반응형

댓글