Javascript async와 await

이연중·2021년 6월 18일

Javascript

목록 보기
6/6

async&await란?

자바스크립트의 비동기 처리 패턴 중 가장 최근에 나온 문법. 기존 비동기 처리 방식인 콜백 함수와 프로미스의 단점을 보완하고 개발자가 읽기 좋은 코드를 작성할 수 있게 도와줌

개발자에게 읽기 좋은 코드

변수와 조건문

var user={
	id:1,
    name:'Josh'
};
if(user.id==1){
	console.log(user.name);
}

이 코드는 user변수에 객체를 할당하고, 조건문으로 아이디를 확인한 뒤 콘솔에 name을 찍는 코드이다.

개발자에게 읽기 좋은 코드는 위에서부터 아래로 한 줄 한 줄 차근히 읽으면서 사고할 수 있는 코드이다.

읽기 좋은 코드와 async&await의 연관성

var user=fetchUser('domain.com/users/1');
if(user.id===1){ //type까지 비교
    console.log(user.name);
}

fetchUser()라는 메서드를 호출하면 앞 코드처럼 사용자 객체를 반환한다고 해보자. 그리고 fetchUser()메서드가 서버에서 사용자 정보를 가져오는 HTTP 통신 코드라 가정하면 위 코드는 async&await 문법이 적용된 형태라고 봐도 된다.

async&await 맛보기

function logName(){
    var uset=fetchUser('domain.com/users/1');
    if(user.id===1){
        console.log(user.name);
    }
}

위 함수를 실행하면 아까와 같이 코드가 동작할 것이며, 여기서 asyncawait를 추가하면

async function logName(){
    var user=await fetchUser('domain.com/users/1');
    if(user.id===1){
		console.log(user.name);
    }
}

이렇게 된다.

async&await 적용된 코드와 그렇지 않은 코드

function logName(){
    var user=fetchUser('domain.com/users/1');
    if(user.id===1){
		console.log(user.name);
    }
}

fetchUser()는 서버에서 데이터를 받아오는 HTTP 통신 코드라고 가정했다. 일반적으로 자바스크립트의 비동기 처리 코드는 콜백을 사용해야 코드의 실행 순서를 보장받을 수 있다.

function logName(){
    var user=fetchUser('domain.com/users/1',function(user){
		if(user.id===1){
			console.log(user.name);
        }
    });
}

비동기 처리를 콜백으로 안해도 될때

function logName(){
    var user=fetchUser('domain.com/users/1');
    if(user.id===1){
		console.log(user.name);
    }
}

서버에서 사용자 데이터를 불러와 변수에 담고, 사용자 아이디가 1이면 사용자 이름을 출력한다.

이 상태에서 비동기로 처리를 하고 싶으면 async&await를 붙이면된다.

위 코드에 async&await 적용

async function logName(){
	var user=await fetchUser('domain.com/users/1');
    if(user.id===1){
		console.log(user.name);
    }
}

async&await 기본 문법

async&await 기본 문법

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

먼저 함수 앞에 async라는 예약어를 붙인다. 그 후 함수 내부 로직 중 HTTP 통신을 하는 비동기 처리 코드 앞에 await를 붙인다. 여기서 주의할 점은 비동기 처리 메서드가 꼭 프로미스 객체를 반환해야 한다는 것이다. 그래야 await가 의도한 대로 동작하기 때문이다.

일반적으로 await의 대상이 되는 비동기 처리 코드는 Axios 등 프로미스를 반환하는 API호출 함수이다.

async&await 간단 예제

function fetchItems(){
	return new Promise(function(resoleve, reject){
		var items=[1,2,3];
        resolve(items);
    });
}

async function logItems(){
    var resultItems= await fetchItems();
    console.log(resultItems);
}

먼저 fetchItems() 함수는 프로미스 객체를 반환하는 함수이다. fetchItems() 함수를 실행하면 프로미스가 이행되며 결과 값은 items 배열이 된다.

logItems() 함수를 실행하면 fetchItems() 함수의 결과 값인 items 배열이 resultItems 변수에 담긴다. 따라서 콘솔에는 [1,2,3]이 출력된다.

await를 사용하지 않으면 데이터를 받아온 시점에 콘솔을 출력할 수 있게 콜백 함수나 .then()등을 사용해야 했을 것이다. 하지만 async await 문법 덕에 비동기에 대한 사고를 하지 않아도 된다.

※참고: 만약 위 코드가 비동기 처리 코드인지 이해가 안되면 아래 함수로 바꿔서 실행해도 상관없다

참고

function fetchItems(){
	return new Promise(function(resolve, reject){
		setTimeout(function(){
			var items=[1,2,3];
            resolve(items)
        },3000);
    });
}

function fetchItems(){
	return new Promise(function(resolve, reject){
		$.ajax('domain.com/items',function(res){
			resolve(res);
        });
    });
}

async&await 실용 예제

async&await의 여러개 비동기 처리 코드 다루기

function fetchUser(){
	var url='https://jsonplaceholder.typicode.com/users/1'
    return fetch(url).then(function(res){
		return res.json();
    });
}

function fetchTodo(){
	var url='https://jsonplaceholder/typicode.com/todos/1';
    return fetch(url).then(function(res){
		return res.json();
    })
}

위 함수들을 각각 실행하면 사용자 정보와 할 일 정보가 담긴 프로미스 객체가 반환된다.

이 두 함수를 이용해 할 일 제목을 출력해 보겠다. 예제 코드의 로직은 아래와 같다.

  1. fetchUser()를 이용하여 사용자 정보 호출
  2. 받아온 사용자 아이디가 1이면 할 일 정보 호출
  3. 받아온 할 일 정보의 제목을 콘솔에 출력
async function logTodoTitle(){
	var user=await fetchUser();
    if(user.id===1){
		var todo=await fetchTode();
        console.log(todo.title);
    }
}

logTodoTitle()을 실행하면 콘솔에 delectus aut autem가 출력될 것이다. 위 비동기 처리 코드를 콜백이나 프로미스로 했다면 코드가 훨씬 더 길어졌을 것이고, 인덴팅 뿐만 아니라 가독성도 좋지 않았을 것이다. 이처럼 async await 문법을 이용하면 기존의 비동기 처리 코드 방식으로 사고하지 않아도 되는 장점이 생긴다.

※참고: fetch() API는 크롬과 같은 최신 브라우저에서만 동작한다.

async&await 예외 처리

async&await에서 예외를 처리하는 방법은 바로 try catch이다.

방금 코드에 try catch 문법 적용

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

위의 코드를 실행하다가 발생한 네트워크 통신 오류뿐만 아니라 간단한 타입 오류 등의 일반적인 오류까지도 catch로 잡아낼 수 있다. 발견된 에러는 error 객채에 담기기 때문에 에러의 유형에 맞게 에러 코드를 처리해주면 된다.

참고

https://joshua1988.github.io/web-development/javascript/js-async-await/

profile
Always's Archives

0개의 댓글