如何在“我的天气”应用程序中仅使用一个功能

时间:2018-03-24 16:17:23

标签: javascript asynchronous xmlhttprequest

在我的天气应用程序中,我需要获取我从ipinfo.io获取的用户位置,以便提供一个http请求,然后我在openweathermap上向另一个api发出另一个http请求.ORG。我的问题是如何改进我的代码。是否可以只生成一个http请求函数,并通过传递不同的参数将其用于调用两个api。请注意,我在每个函数中设置了一些特定于该函数的变量。我不认为可以在函数范围之外使用这些变量。 这是我的index.js

/* 
 Weather App Javascript code
 author: George Louis
 date:   3/11/2018
 purpose: get local weather
*/
window.onload = function() {
    //variables
    var ipUrl = "https://ipinfo.io/json";               
    var appid = "appid=8e1880f460a20463565be25bc573bdc6";
    var location = document.getElementById("location"); 
    var currentDate = new Date();
    var dayNight = "day";   

    //setting the date
    var dateElem = document.getElementById("date");
    var strDate = currentDate.toString();
    dateElem.innerHTML = strDate.substring(0, strDate.length-18)

    //calling ipinfo.io/json function
    httpReqIpAsync(ipUrl);                          

    //request to ipinfo.io/json
    function httpReqIpAsync(url, callback) {
        var httpReqIp = new XMLHttpRequest();
        httpReqIp.open("GET", url, true)
        httpReqIp.onreadystatechange = function() {
            if(httpReqIp.readyState == 4 && httpReqIp.status == 200) {
                var jsonIp = JSON.parse(httpReqIp.responseText)
                var ip = jsonIp.ip;
                var city = jsonIp.city;
                var country = jsonIp.country;
                location.innerHTML = `${city}, ${country}`;
                var lat = jsonIp.loc.split(",")[0];
                var lon = jsonIp.loc.split(",")[1];
                console.log(lat+" "+lon)
                var weatherApi = `http://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&${appid}`;
                //calling openweathermap api function
                httpReqWeatherAsync(weatherApi);
            }
        }
        httpReqIp.send();               
    }

    //request to openweathermap.com json
    function httpReqWeatherAsync(url, callback) {
        var httpReqWeather = new XMLHttpRequest();
        httpReqWeather.open("GET", url, true);
        httpReqWeather.onreadystatechange = function() {
            if(httpReqWeather.readyState == 4 && httpReqWeather.status == 200) {
                var jsonWeather = JSON.parse(httpReqWeather.responseText);
                console.log(jsonWeather)
                var weatherDesc = jsonWeather.weather[0].description;
                var id = jsonWeather.weather[0].id;
                var icon = `<i class="wi wi-owm-${id}"></i>`
                var temperature = jsonWeather.main.temp;
                var tempFaren = Math.round(1.8 * (temperature - 273) + 32)
                // console.log(tempFaren)
                var humidity = jsonWeather.main.humidity;
                var windSpeed = jsonWeather.wind.speed; 
                //converting visibility to miles 
                var visibility = Math.round(jsonWeather.visibility / 1000);
                // console.log(visibility)

                //find whether is day or night
                var sunSet = jsonWeather.sys.sunset;
                //sunset is 10 digits and currentDate 13 so div by 1000
                var timeNow = Math.round(currentDate / 1000);
                console.log(timeNow + "<" + sunSet +" = "+(timeNow < sunSet))
                dayNight = (timeNow < sunSet) ? "day" : "night";
                //insert into html page
                var description = document.getElementById("description");
                description.innerHTML = `<i id="icon-desc" class="wi wi-owm-${dayNight}-${id}"></i><p>${weatherDesc}</p>`;
                var tempElement = document.getElementById("temperature");
                tempElement.innerHTML = `${tempFaren}<i id="icon-thermometer" class="wi wi-thermometer"></i>`   ;
                var humidityElem = document.getElementById("humidity");
                humidityElem.innerHTML = `${humidity}%`;
                var windElem = document.getElementById("wind");
                windElem.innerHTML = `${windSpeed}m/h`;
                var visibilityElem = document.getElementById("visibility");
                visibilityElem.innerHTML = `${visibility} miles`;
            }
        }
        httpReqWeather.send();
    }                           
}

1 个答案:

答案 0 :(得分:0)

如果您愿意,可以使用request的{​​{1}}现代方式代替fetch。您也可以利用解构。这就是我要做的事情:

function httpReqIpAsync(url, callback) {
  fetch(url)
    .then(response => response.json())
    .then(jsonIp => {
      const { ip, city, country } = jsonIp;
      location.textContent = `${city}, ${country}`;
      const [lat, lon] = jsonIp.loc.split(",");
      const weatherApi = `http://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&${appid}`;
      return [weatherApi, callback];
    })
    .then(httpReqWeatherAsync)
}

//request to openweathermap.com json
function httpReqWeatherAsync([url, callback]) {
  // ...

由于每个请求都是单独的,我认为将它们放在单独的函数中更有意义,而不是将它们合并在一起。