자바스크립트에서 api를 사용하여 데이터를 가져와서 가공하는 작업에 대하여 좀더 공부하는 중입니다.
자바스크립트 fetch API
자바스크립트에서는 fetch로 리소스를 비동기 요청을 할 수 있습니다. 주로 API를 호출하고 응답 데이터를 받아오는 데에 주로 사용합니다.
fetch 에는 기본적으로 첫 번째 인자에 요청할 url이 들어갑니다. default로 http 메소드 중 GET으로 동작합니다.
호출 시 해당 주소에 요청을 보낸 다음, 응답 객체(object Response)를 받습니다.
첫 번째 then에서 그 응답을 받고 .json() 메서드로 파싱한 json 값을 리턴합니다.
그러면 그 다음 then에서 리턴받은 json 값을 받고, 원하는 처리를 할 수 있습니다.
위 코드를 ES6 문법에서 도입된 화살표 함수로 간소화하면 다음과 같습니다.
화살표 함수 문법의 경우 첫번째 then 처럼 body 부분이 단 한줄일 경우 { } 를 생략하며 => 다음에 쓴 값 자체가 리턴 됩니다.
다음과 같이 API 호출을 통해 리소스를 받고 그 값으로 어떤 변수를 초기화해야 하는 경우가 있다고 가정해 보겠습니다.
fetch가 비동기 작업을 담당하는 것에 유의한다면, 호출을 통해 응답 데이터 및 json 값 대입 전에 이미 console.log(text) 가 먼저 호출되고, 따라서 빈 문자열만이 콘솔에 출력될 것입니다.
비동기 처리라는 것은 쉽게 말하자면 시간이 소요되는 작업이 완료될 때까지 계속 기다리지 않고 따로 처리하며, 일단 다른 코드들도 먼저 실행할 수 있게끔 하는 작업이기 때문입니다.
그러므로 위처럼 순서가 정확히 보장되지 못하는 상황에 처할 수 있게 되는 것입니다.
그러므로 비동기 처리로 얻은 데이터를 이용해야 하는 부분이 있을 경우, 비동기 처리가 모두 완료된 뒤에 변수 등 초기화 작업을 진행하는 등 비동기 작업의 흐름을 제어해야 할 것입니다.
일반적으로 알려진 callback 함수 를 사용한 비동기 작업 처리를 하자면 다음과 같습니다.
그런데 위에서 callBackFunc 함수에는 text 라는 변수가 선언된 적이 없는데도 거기에 값을 대입하고 있습니다. 어떻게 가능한 일일까요? 바로 클로저에 해답이 있습니다.
이 코드에서 한 가지 짚을 수 있는 부분은 콜백함수가 클로저로 사용되었다는 것입니다.
즉, getTitle이라는 외부 함수 내부에 callback 이라는 내부 함수가 리턴되고 있는데 이 함수는 외부 함수의 자유변수인 text를 여전히 참조할 수 있습니다.
따라서 콜백함수에서는 getTitle 의 변수 text에 응답받은 데이터를 넣은 것이며, 이것을 콘솔에 출력하고 있는 것입니다.
async/await 을 사용하여 좀 더 코드를 간단히 작성해 보겠습니다.
getTitle 함수는 fetch를 통해 호출한 API로부터 응답 데이터 받고 JSON 파싱하여 리턴하는 부분만 담당합니다. 그리고 그 데이터를 받아서 처리하는 함수가 exec 입니다.
이 때, await는 비동기 작업의 결과값을 얻을 때까지 기다려 줍니다. 그리고 getTitle 함수로부터 정상적으로 값을 받은 다음, token 변수에 그 값을 저장하고 있습니다.
await 는 Promise 객체를 리턴하는 부분 앞에만 붙일 수 있습니다. 이 때, fetch API를 통해 받은 response 데이터는 Promise 객체라서 사용이 가능합니다.
또한 await를 함수 내에서 사용하려면 그 함수에는 반드시 async 키워드가 붙어 있어야 합니다.
이 점에 유의한다면, 콜백 함수를 작성할 필요 없이 거의 동기식 코드를 짜는 것처럼 작성할 수 있습니다.
참고로 async 가 붙은 함수는 항상 리턴값이 Promise가 됩니다. 따라서 아래와 같은 코드도 가능합니다.
getTitle 함수가 리턴하는 response는 프로미스 객체가 되므로 then을 사용하여 값을 처리할 수 있습니다.
만약 콜백함수로 이전 비동기 작업으로부터 처리 완료한 값을 받고, 다음 작업들을 처리할 경우 자칫하면 콜백 지옥에 빠질 수도 있습니다.
(어떤 비동기 처리 이후 그 결과를 받고 매개변수로 넘겨진 콜백함수에 그 값이 전달되고, 다시 거기서 비동기 처리 이후 그 결과를 다음 콜백 함수에 전달되고, …)
콜백 지옥은 개수가 많아질수록 코드가 보기 힘들어지는 단점이 존재합니다.
따라서 async/await는 여러 API를 호출하여 그 값들을 이용해야 할 때 진가를 발휘할 수 있습니다.
참고 : Online JavaScript Editor (playcode.io) 에서는 자바스크립트 코드를 작성한 후, 온라인에서 손쉽게 실행하고 결과를 확인할 수 있습니다.