【问题标题】:How to make synchron request with fetch?如何使用 fetch 发出同步请求?
【发布时间】:2019-01-25 12:07:56
【问题描述】:

我正在使用纯 JavaScript 创建天气应用程序。我正在从某个 api 获取天气数据,我希望我的页面等待接收该数据,然后使用检索到的数据加载 html。我尝试使用 Promise 和 async/await 来完成这项工作,但无法完成工作。

这是我的代码:

import getWeather from './getWeatherState';

const detailedForecast = () => {
    let city = document.querySelector('.weather-forecast__city');
    let date = document.querySelector('.weather-forecast__date');
    let currentDate = new Date();
    let weekDays = ["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"];
    let monthNames = ["January", "February", "March", "April", "May", "June","July", "August", "September", "October", "November", "December"]; 
    let celsius = document.querySelector('.weather-forecast__celsius');
    let description = document.querySelector('.weather-forecast__figcaption');
    let pressure = document.querySelector('.weather-forecast__pressure');
    let humidity = document.querySelector('.weather-forecast__humidity');
    let windSpeed = document.querySelector('.weather-forecast__wind-speed');
    let geocoder,latitude,longitude,currentCity;
    let detailedForecast = {

    }

    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(geoSuccess, geoError);
        function geoSuccess(position) {
            let lat = position.coords.latitude;
            let lng = position.coords.longitude;
            getCurrentCity(lat,lng);
        }

        function geoError() {
            alert('Geocoder failed');
        }
        geocoder = new google.maps.Geocoder();

        function getCurrentCity(lat, lng) {
            let currentCity = new google.maps.LatLng(lat, lng);
            geocoder.geocode({'location': currentCity}, (results, status) => {
                if (status = google.maps.GeocoderStatus.OK) {
                    latitude = results[0].geometry.location.lat();
                    longitude = results[0].geometry.location.lng();
                    currentCity = results[0].address_components[4].short_name;

                    async function getData() {
                        await getWeather(currentCity, detailedForecast);
                        console.log(111);
                    }

                    getData();
                    console.log(detailedForecast, 'detailedForecast');
                    city.innerHTML = currentCity;
                    date.innerHTML = weekDays[currentDate.getDay()] + ', ' + monthNames[currentDate.getMonth()] + ' ' + currentDate.getDate() + ', ' + currentDate.getHours() + ':' + currentDate.getMinutes();
                    celsius.innerHTML = detailedForecast.currentTemp;
                    description.innerHTML = detailedForecast.weatherDescription;
                    pressure.innerHTML = detailedForecast.atmosphericPressure;
                    humidity.innerHTML = detailedForecast.humidity;
                    windSpeed.innerHTML = detailedForecast.windSpeed;
                }
            })
        }
    } else {
        alert('Geoloaction is not supported by this browser');
    }
}

export default detailedForecast;

这里是一个获取的函数:

export default (currentCity, detailedForecast) => {
    fetch(`http://api.openweathermap.org/data/2.5/forecast?q=${currentCity},am&appid=bdb69b5685832284db539510d237124e`)
        .then(res => res.json())
        .catch(error => console.error('Error:', error))
        .then(res => {
            detailedForecast.currentTemp = res.list[0].main.temp - 273.15;
            detailedForecast.windSpeed = res.list[0].wind.speed;
            detailedForecast.weatherDescription = res.list[0].weather[0].description;
            detailedForecast.humidity = `${res.list[0].main.humidity}%`;
            detailedForecast.atmosphericPressure = `${res.list[0].main.pressure}mm Hg`;
            console.log(res, 'weather response');
    });
}

这是我的应用程序的屏幕,我需要加载带有未定义数据的页面。最后一个控制台在 fetch.then()

【问题讨论】:

  • 你忘记返回承诺链了。
  • 我应该在哪里退货?

标签: javascript async-await fetch es6-promise


【解决方案1】:

这种方法行不通,因为要在网页上设置值 - 你需要先渲染它,这样 JS 才能访问 DOM 并找到必要的元素。

如果您关心页面外观 - 考虑使用某种 loader 在数据出现之前隐藏页面。

在 getWeatherState 中,您有一个获取请求,该请求刚刚触发,但您的代码不会等待它,因为该函数不会返回任何承诺。试试这个:

export default (currentCity, detailedForecast) => {
    return fetch(`http://api.openweathermap.org/data/2.5/forecast?q=${currentCity},am&appid=bdb69b5685832284db539510d237124e`)
        .then(res => res.json())
        .catch(error => console.error('Error:', error))
        .then(res => {
            return {
                currentTemp: res.list[0].main.temp - 273.15,
                windSpeed: res.list[0].wind.speed,
                weatherDescription: res.list[0].weather[0].description,
                humidity: `${res.list[0].main.humidity}%`,
                atmosphericPressure: `${res.list[0].main.pressure}mm Hg`
            };
        });
}

然后,等待 Promise 返回一个 main 函数和assign 结果:

getData().then(result=>{
    Object.assign(detailedForecast, result);
    console.log(detailedForecast, 'detailedForecast');
    ...
});

【讨论】:

    猜你喜欢
    • 2017-02-19
    • 2017-06-02
    • 2012-06-02
    • 1970-01-01
    • 1970-01-01
    • 2015-05-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多