기록하기

Promise 객체 / async 와 await 본문

language/javascript

Promise 객체 / async 와 await

jjungdev 2022. 5. 8. 17:10

Promise 는 "비동기 통신을 하는데 서버로 응답이 왔을 때 그걸 호출한 함수에서 알 수 있도록 약속할게" 라는 의미를 가지고 있다.

즉, 비동기 통신을 하게 될 경우 특정 코드 실행이 완료될 때까지 기다리지 않고 다음 코드를 수행하는 것을 의미하는데 이 특성 때문에 처리 결과를 받아와야 하는 경우 데이터를 받아오지 못하는 문제가 발생하게 된다. 이를 위해 나온 개념이 Promise 이다.

 

기존 XMLHttpRequest 객체를 사용하여 통신을 하는 코드를 살펴보도록 하겠다.

function getData() {
	const xhr = new XMLHttpRequest();
    
    xhr.open("GET", "http://localhost:3000/posts");
    xhr.setRequestHeader("content-type", "application/json");
    xhr.send();
    
    xhr.onload = () => {
    	if (xhr.status === 200) {
        	const res = JSON.parse(xhr.response);
        } else {
        	console.log(xhr.status, xhr.statusText);
        }
    }
}

여기서 getData 함수 호출 결과를 함수 밖에서 가져오고 싶어서 아래와 같이 코드를 작성하게 되면 비동기 통신의 특징으로 인해서 가져올가 없다. 이 코드의 실행이 끝날 때까지 기다려주지 않고 다음 코드를 실행하기 때문에 아래와 같이 작성하게 되면 오류가 발생하게 된다.

function getData() {
	...
}

const data = getData();
console.log(data);

 

여기서 활용할 수 있는 개념이 Promise 이다.

Promise 는 비동기 연산이 종료된 이후에 결과값과 실패 사유를 처리하기 위한 처리기라고 볼 수 있다.

function getData(url) {
	return new Promise((resolve, reject) => {
    	const xhr = new XMLHttpRequest();
        
        xhr.open("GET", url);
        xhr.setRequestHeader("content-type", "application/json");
        xhr.send();
        
        //서버로부터 응답을 받으면 실행
        //resolve : 성공할 경우
        //reject : 실패할 경우
        xhr.onload = () => {
        	if (xhr.status === 200) {
            	const res = JSON.parse(xhr.response);
                console.log(res);
                resolve(res);
            } else {
            	console.log(xhr.status, xhr.statusText);
                reject(res.status);
            }
        }
    });
}

getData("http://localhost:3000/posts").then((res) => {
	console.log(res);
});

이 경우 아래 getData 를 호출하는 코드에서 그 결과가 오면 then 을 통해 로직을 처리할 수 있다.

 

추가적으로, Promise 에는 아래 3가지 상태가 있다.

  • Pending : 비동기 처리 로직이 아직 완료되지 않은 상태
  • Fulfilled : 비동기 처리가 완료되어 프로미스가 결과값을 반환해준 상태
  • Rejected : 비동기 처리가 실패하거나 오류가 발생한 상태

Pending 의 경우에는 대기 상태이며, 위에서 resolve(res) 가 실행될 경우 Fulfilled 상태, reject(res) 가 실행될 경우 Rejected 상태인 것이다. 

 


async 와 await

여기서 async 와 await 문법을 사용하면 Promise 를 더 편하게 사용할 수 있다.

먼저, async, await 이란 자바스크립트 비동기 처리 패턴 문법이다. async 가 붙은 함수는 Promise 를 반환하고, await 이 붙은 곳에서는 Promise 가 처리될 때까지 기다린 후에 다음 코드를 실행하게 된다. 

await 을 사용하지 않으면 위에서 작성한 코드와 같이 .then() 이나 콜백 함수를 통해 결과값을 받아와야하지만 async, await 을 사용하면 아래와 같이 간결하게 코드를 작성할 수 있다.

async function getData() {
    //이게 끝날 때까지 아래 코드 실행 안 된다.
    const res = await fetch("http://localhost:3000/posts");
    const json = await res.json();

    const res2 = await fetch("http://localhost:3000/posts");
    const json2 = await res2.json();
}

 

 

 

참고

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise

 

Promise - JavaScript | MDN

Promise 객체는 비동기 작업이 맞이할 미래의 완료 또는 실패와 그 결과 값을 나타냅니다.

developer.mozilla.org

https://joshua1988.github.io/web-development/javascript/promise-for-beginners/

'language > javascript' 카테고리의 다른 글

javascript 에서 DOM 을 조작하는 방법  (0) 2022.05.15
String 오브젝트 - padStart(), padEnd()  (0) 2022.05.01