【问题标题】:How can I Make Use of Only One Function with My Weather App如何在我的天气应用程序中仅使用一项功能
【发布时间】:2018-03-25 00:33:21
【问题描述】:

在我的天气应用程序中,我需要从 ipinfo.io 获取用户位置,这是一个 http 请求,然后我向 openweathermap.org 上的另一个 api 发出另一个 http 请求。我的问题是如何改进我的代码。是否可以只制作一个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();
    }                           
}

【问题讨论】:

  • 为什么你不使用fetch() 而不是旧的XMLHttpRequest
  • 你能给我一个教程,而不是冗长的文档。谢谢
  • 查看“概念和用法”下黄色块中的注释

标签: javascript asynchronous xmlhttprequest


【解决方案1】:

如果您愿意,您可以使用requestfetch 的现代方式。您还可以利用解构。这就是我会做的:

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]) {
  // ...

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

【讨论】:

  • fetch() 使得跟踪separation of concernes principle 变得如此容易,因此httpReqIpAsync() 应该只返回response.json() 的结果,其他所有事情都应该在它之外在一个单独的.then() 中完成称呼。 httpReqIpAsync() 没有理由知道有关使用的天气 API 的任何信息。
猜你喜欢
  • 1970-01-01
  • 2013-02-26
  • 2019-02-10
  • 2015-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-10
  • 1970-01-01
相关资源
最近更新 更多