如何将两个提取请求合并到同一数组中?

时间:2019-05-05 11:07:26

标签: javascript reactjs

我试图在一个调用中合并两个获取请求,以便可以将所有数据存储在同一数组中。

我尝试了Promise.all方法,但我不知道这是否是正确的方法。

getWeather = async (e) => {
e.preventDefault();
const city = e.target.elements.city.value;
//const api_call = await
const promises = await Promise.all([
   fetch(`http://api.openweathermap.org/data/2.5/weather?q=${city}&units=metric&APPID=${API_KEY}`),
  fetch(`http://api.openweathermap.org/data/2.5/forecast?q=${city}&units=metric&APPID=${API_KEY}`)
])

const data = promises.then((results) =>
Promise.all(results.map(r => r.text())))
.then(console.log)

该代码实际上有效,我正在获取数据,但我无法理解json响应。

  (2) ["{"coord":{"lon":-5.93,"lat":54.6},"weather":[{"id"…7086601},"id":2655984,"name":"Belfast","cod":200}", "{"cod":"200","message":0.0077,"cnt":40,"list":[{"d…on":-5.9301},"country":"GB","population":274770}}"]

我应该如何设置状态? 我的状态是这样设置的,只打了一个电话。

  if (city) {
  this.setState({
    temperature: data[0].main.temp,
    city: data[0].name,

有更好的方法吗?

2 个答案:

答案 0 :(得分:3)

我愿意:

  getWeather = async (e) => {
   e.preventDefault();

   const fetchText = url => fetch(url).then(r => r.json()); // 1

   const /*2*/[weather, forecast] = /*3*/ await Promise.all([
     fetchText(`.../weather`),
     fetchText(`.../forecast`)
   ]);

   this.setState({ temperature: weather.temp, /*...*/ });
 }

1:使用一个小的助手,您不必两次调用Promise.all。这样,两个请求就并行完成了(并且您应该使用.json()来将其解析为JSON)。

2:通过数组解构,您可以轻松获得promises结果。

3:通过await,您可以从async函数中获得实际的好处:您不需要嵌套的.then

答案 1 :(得分:1)

您可以按照以下更简洁的方式进行编写,并对数据进行分类

const success = res => res.ok ? res.json() : Promise.resolve({});

const weather = fetch(`http://api.openweathermap.org/data/2.5/weather?q=${city}&units=metric&APPID=${API_KEY}`)
.then(success);

const forecast = fetch(`http://api.openweathermap.org/data/2.5/forecast?q=${city}&units=metric&APPID=${API_KEY}`)
.then(success);

return Promise.all([weather, forecast])
.then(([weatherData, forecastData]) => {
const weatherRes = weatherData;
const ForecastRes = forecastData; // you can combine it or use it separately
})
.catch(err => console.error(err));
}