어제와 다르게 오늘 스프린트 과제는 Node.js 환경을 떠나, 브라우저에서 진행한다. (Node.js 환경에는 fetch API가 내장 모듈로 제공되지 않는다)
이번에는 fetch를 이용해 HTTP 요청을 보내고, 응답을 받는 연습을 해보았다.
터미널에서 npm run server:part-3 으로 서버를 실행하였다. 서버를 실행한 상태에서는 다음 URL을 통해 정보를 얻어올 수 있다.
최신 뉴스의 경우 데이터 형태가 {data: [{}, {}, ..., {}]}
--> 이와 같이 객체 안 data의 속성값으로 들어가 있고,
날씨 정보의 경우 데이터 형태가 {}
이렇게 단일 객체로 되어져 있다.
fetch(url)
을 하게 되면 받아온 데이터는 응답객체 형태이다. 콘솔로그에 찍어보면 확인해 볼 수 있다.
따라서 json() 메소드를 활용하여, 응답을 JSON 형태로 변환시켜서 다음 Promise로 전달하였다.
빈 객체 obj에다가 newsURL에서 긁어온 객체의 data속성값을 추가해주었고, weatherURL에서 긁어온 객체는 통째로 추가해주었다.
const { response } = require("express");
var newsURL = 'http://localhost:5000/data/latestNews';
var weatherURL = 'http://localhost:5000/data/weather';
function getNewsAndWeather() {
// TODO: fetch을 이용해 작성합니다
// TODO: 여러개의 Promise를 then으로 연결하여 작성합니다
let obj = {}
return fetch(newsURL)
.then((response)=>response.json())
.then((response)=> {
obj.news = response.data// obj ={newsURL정보}
return fetch(weatherURL)
}).then((response)=>response.json())
.then((response)=>{
obj.weather = response
return obj;
})
}
if (typeof window === 'undefined') {
module.exports = {
getNewsAndWeather
}
}
Promise.all()에서 전달인자는 항상 array와 같이 순회 가능한 객체가 들어간다.
더 자세히 알아보면...
Promise의 all 메서드는 promise로 구성된 배열을 인자로 받아 새로운 promise를 리턴한다. 리턴된 새로운 promise는 실행할 때 배열의 모든 promise를 실행하여 그 결과가 모두 나올 때까지 기다린 후 배열로 리턴한다. 즉 .then 메서드를 호출하면 promise를 모두 실행하고 그 결과를 배열로 만들어서 .then 메서드의 콜백 함수의 인자로 결과를 전달한다.
예시.
var userList = ['kim', 'lee', 'jung'];
var promiseList = [];
Promise.all(userList)
.then((res)=>{
return console.log(res +' is lucky');
}) //kim,lee,jung is lucky
var userList = ['kim', 'lee', 'jung'];
//var promiseList = [];
Promise.all(userList)
.then((res)=> console.log(res)) //["kim", "lee", "jung"]
["kim", "lee", "jung"]+' is lucky'//"kim,lee,jung is lucky"
어쨌든 Promise.all에 넣어주기 전에 newsURL과 weatherURL 정보를 응답형태에서 JSON 형태로 변환해주고(response 객체 --> promise 객체로) 변수로 넣어주었다.
그런 다음 **Promise.all([news, weather])
를 통하여 각 promise 안에 숨겨져 있는 전달값들을 빼내주고,**
그 전달값을 원하는 형태({news: response[0].data, weather: response[1]}
)로 리턴해주었다.
var newsURL = 'http://localhost:5000/data/latestNews';
var weatherURL = 'http://localhost:5000/data/weather';
function getNewsAndWeatherAll() {
// TODO: Promise.all을 이용해 작성합니다
let news = fetch(newsURL).then((response)=>response.json())
let weather = fetch(weatherURL).then((response)=>response.json())
return Promise.all([news, weather])
.then((response) => {
return {news: response[0].data, weather: response[1]}
})
}
if (typeof window === 'undefined') {
module.exports = {
getNewsAndWeatherAll
}
}
각 url으로부터 fetch를 해오게 되면 응답형태로 있기 때문에 이번에도 각각 json형태로 전환해주고 변수에 저장하였다.
async/await
방식을 적용하게 되면 promise 객체안에 숨겨져 있는 전달값을 끄집어내 주니까(--> 이 부분이 포인트!!!), 바로 리턴을 해주면 된다.
var newsURL = 'http://localhost:5000/data/latestNews';
var weatherURL = 'http://localhost:5000/data/weather';
async function getNewsAndWeatherAsync() {
// TODO: async/await 키워드를 이용해 작성합니다
let news = await fetch(newsURL).then((value)=>value.json())
let weather = await fetch(weatherURL).then((value)=>value.json())
return {news: news.data, weather: weather}
}
if (typeof window === 'undefined') {
module.exports = {
getNewsAndWeatherAsync
}
}
중간중간에 콘솔로그로 전달값들의 형태를 확인해보니 훨씬 이해하는데 도움이 되었다~!