본문 바로가기
javascript

async-await를 이해하기 위한 노력

by 바나냥 2020. 9. 23.

async-await가 가장 최신의 비동기 문법이고, callback, promise보다 가독성이 좋다는 것은 알고 있다.

하지만 async-await를 언제, 왜 써야 하는지 잘 이해가 되지 않았다.

 

 

비동기가 뭔지부터 알자.

function getData() {
	var tableData;
	$.get('https://domain.com/products/1', function(response) {
		tableData = response;
	});
	return tableData;
}

console.log(getData());

 

대표적인 비동기 사례로 jQuery의 $.get이 있다.

위 코드를 실행하면 콘솔에는 undefined가 찍힌다.

왜냐하면 $.get에서 데이터를 받아올 때까지 기다리지 않고 tableData를 return하기 때문이다.

이렇게 로직의 실행이 끝날 때까지 기다려주지 않고 다음 코드를 실행하는 것이 비동기 처리이다.

 

 

console.log('Hello');
// #2
setTimeout(function() {
	console.log('Bye');
}, 3000);

console.log('Hello Again');

 

다음으로는 setTimeout()이 있다.

위 코드를 실행하면 콘솔에는 Hello - Hello Again - Bye 순으로 찍히게 된다.

setTimeout()이 실행된 후 3초 뒤에 다음 코드를 실행하는 것이 아니라, setTimeout()을 실행하고 다음 코드를 실행한 후 3초 뒤에 출력하기 때문이다.

 

 

callback지옥과 then지옥

그렇다면 여러가지 비동기 코드들을 원하는 순서대로 처리하고 싶다면?

async-await를 배우기 앞서 callback과 promise를 한번 살펴보겠다.

 

 

 

 

new Promise(function(resolve, reject){
  setTimeout(function() {
    resolve(1);
  }, 2000);
})
.then(function(result) {
  console.log(result); // 1
  return result + 10;
})
.then(function(result) {
  console.log(result); // 11
  return result + 20;
})
.then(function(result) {
  console.log(result); // 31
});

 

지옥에서 온 콜백. 그렇다고 promise도 엄청나게 간결해 보이지는 않는다.

비동기 처리할 로직이 많아지면 무한 덴덴덴(그래서? 그래서? 그래서?)이 될 것이다.

 

function getData() {
	var tableData;
	$.get('https://domain.com/products/1', function(response) {
		tableData = response;
	});
	return tableData;
}

console.log(getData());

 

위 코드(비동기가 뭔지부터 알자 예제1)를 순차적으로 처리하기 위해 각각 callback과 promise를 사용하면 아래와 같다.

 

function getData(callbackFunc) {
	$.get('https://domain.com/products/1', function(response) {
		callbackFunc(response); // 서버에서 받은 데이터 response를 callbackFunc() 함수에 넘겨줌
	});
}

getData(function(tableData) {
	console.log(tableData); // $.get()의 response 값이 tableData에 전달됨
});

 

function getData(callback) {
  // new Promise() 추가
  return new Promise(function(resolve, reject) {
    $.get('url 주소/products/1', function(response) {
      // 데이터를 받으면 resolve() 호출
      resolve(response);
    });
  });
}

// getData()의 실행이 끝나면 호출되는 then()
getData().then(function(tableData) {
  // resolve()의 결과 값이 여기로 전달됨
  console.log(tableData); // $.get()의 reponse 값이 tableData에 전달됨
});

 

이제 async-await를 쓰자.

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

 

위 코드를 보니 async-await가 promise보다 간결하다고 한 이유를 알겠다.

async-await를 사용하면 콜백 함수나 then을 쓰지 않아도 코드를 작성한 순서대로 비동기를 처리할 수 있다는 것이다!

이제 async-await를 이용하여 promise 객체들을 반환해보자.

 

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

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

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

 

이제 감이 잡힌다.. 하지만 또 까먹고 헷갈리겠지.

async-await 안에 왜 promise가 들어가는지 이해가 안됐었는데 비동기에 대한 개념을 다시 짚게 되었다.

아래는 예전에 공부했던 뉴스 뷰어 만들기.

axios를 왜 async-await로 처리하는지 이해하기.

 

const fetchData = async () => {
            try {
                const response = await axios.get(
                    `https://newsapi.org/v2/top-headlines?country=kr${query}&apiKey=54cfead6486041a2af9ec1cf6e98d343`,
                );
                setArticles(response.data.articles);
            } catch (e) {
                console.log(e)
            }
        };

댓글