하루하루 꾸준히, 인생은 되는대로

자바스크립트

자바스크립트의 비동기 처리 async/await

긤효중 2022. 12. 20. 16:12

ECMAScript 2017 (ES8)부터 자바스크립트의 비동기 처리를 도와주는 async/await가 등장하였습니다.

promise로도 비동기 처리가 가능한데, 왜 async/await가 등장하였을까요?

 

"Promise도 가독성이 그렇게 좋지 않다" 가 가장 큰 이유입니다.

코드의 가독성은 개발자에게 중요하고, async/await는 개발자에게 읽기 좋은 코드를 만들어줍니다.

 

const makeRequest = () => {
	getJson().then(data=>{
    	console.log(data);
        return 'done';
     })
   } 
   
 makeRequest();

 

const makeRequest = async () => {
	console.log(await getJson())l
    return 'done';
 }

 

Promise와 async/await로 작성한 코드 중 async/await를 사용한 코드가 뭔가 더 직관적이고 간결한 것을 확인할 수 있습니다.

 

async함수의 기본적인 문법

 

async함수async키워드를 이용해 정의한 함수입니다.

함수 앞에 async키워드를 붙여주면 됩니다. 그 후, 비동기 처리를 담당하는 코드 앞await키워드를 붙여줍니다.

(HTTP통신 등)

async function 함수명(){
	await 비동기_처리_메서드명();
}

axios 인스턴스를 만들고, GET요청을 보내는 코드를 작성해보겠습니다.(airtableInstance는 axios 인스턴스입니다)

 

async function getTodos() {
    const response = await airtableInstance.get('/todos').then((Response) => {
      console.log(Response);
    });
  }

  getTodos();

 

이렇게 함수 이름 앞에 async키워드를 붙이고 비동기적인 작업을 하는 코드 앞에 await를 붙이는 것을 확인할 수 있습니다.

화살표 함수로도 표현을 할 수 있습니다. 위의 코드를 화살표 함수를 이용해 바꿔본다면 다음과 같습니다.

const getTodos = async () => {
    const response = await airtableInstance.get('/todos').then((Response) => {
      console.log(Response);
    });
  };

  getTodos();

async는 Promise 객체를 반환합니다.

async function asyncFunc(){
	return 'value';
}

asyncFunc().then((result) => {
	console.log(result);
}

Promise 객체를 반환하기 떄문에 Promise에서 쓸 떄처럼 then()을 사용할 수 있습니다. 

이때,then의 파라미터로 넘겨준 result는 asyncFunc()가 반환하는 값입니다.

 

await키워드

await키워드는 프로미스가 비동기 처리가 수행된 상태가 될떄까지 기다리다, 비동기 처리가 수행된 상태이면

프로미스가 resolve한 처리 결과를 반환합니다.

 

URL로 요청을 보내면 JSON형식으로 해당 아이디의 정보를 알려주는 API를 async/await로 호출합니다.

https://api.github.com/users/userid 

 

첫번째 await fetch는 HTTP요청에 대한 서버의 응답이 와서, fetch가 변환한 프로미스가 비동기 처리가 수행된 상태가 될때까지 대기합니다.

 

그 후, 프로미스가 비동기 처리를 수행하면, 프로미스가 resolve한 결과가 res에 할당됩니다

 

async & await의 예외 처리

async & await에서 예외를 처리하는 방법은 try catch입니다. 

 

async function logTodoTitle() {
  try {
    var user = await fetchUser();
    if (user.id === 1) {
      var todo = await fetchTodo();
      console.log(todo.title); // delectus aut autem
    }
  } catch (error) {
    console.log(error);
  }
}

async 함수 내에서 catch문을 사용해서 에러 처리를 하지 않으면 async함수는 발생한 에러를 reject하는 프로미스를 반환합니다.

 

async()를 호출하고, Promise.prototype.catch의 후속 메서드로 에러를 캐치할 수도 있습니다.

 

async function logTodoTitle() {
    var user = await fetchUser();
    var todo = await fetchTodo();
    return todo.title; 
};
//resolve,reject
logTodoTitle().then().catch();