简体   繁体   English

重构来自 API 调用的重复 if 语句

[英]Refactoring repetitive if statements from API call

I have used four very similar if statements in order to choose which weather icon to display for my weather app project.我使用了四个非常相似的 if 语句来选择要为我的天气应用程序项目显示的天气图标。

I have tried using for loops, forEach, googling, experimenting but I can't quite seem to refactor it and keep the functionality.我尝试过使用 for 循环、forEach、谷歌搜索、实验,但我似乎无法重构它并保留功能。

I have taken the first four items of an array for weather forecasts from OpenWeatherMap, and depending on the weather code of a specific array (which represents a time), I display the respective icon.我从 OpenWeatherMap 获取了天气预报数组的前四项,并根据特定数组(表示时间)的天气代码,显示相应的图标。

I have the functionality but I have a lot of repeated code, will someone please help me refactor this or point me in the right direction?我有这个功能,但是我有很多重复的代码,有人可以帮我重构这个或指出我正确的方向吗? This is my first proper project so please be gentle: Thank you for any help in advance :)这是我的第一个适当的项目,所以请温柔:谢谢您提前提供的帮助:)

const getForecast = async (api) => {
    try {
        const res = await axios.get(api);
        console.log(res);

        const weather1 = res.data.list[0].weather[0].main;
        const time1 = res.data.list[0].dt_txt.substr(11, 15);
        const weather2 = res.data.list[1].weather[0].main;
        const time2 = res.data.list[1].dt_txt.substr(11, 15);
        const weather3 = res.data.list[2].weather[0].main;
        const time3 = res.data.list[2].dt_txt.substr(11, 15);
        const weather4 = res.data.list[3].weather[0].main;
        const time4 = res.data.list[3].dt_txt.substr(11, 15);

        forecastTime1.textContent = time1;
        forecastTime2.textContent = time2;
        forecastTime3.textContent = time3;
        forecastTime4.textContent = time4;

        if (weather1 === "Thunderstorm") {
            forecastDisplay1.src = `img/thunder.svg`;
        } else if (weather1 === "Drizzle") {
            forecastDisplay1.src = `img/drizzle.svg`;
        } else if (weather1 === "Rain") {
            forecastDisplay1.src = `img/rain.svg`;
        } else if (weather1 === "Snow") {
            forecastDisplay1.src = `img/snowy.svg`;
        } else if (
            weather1 === "Mist" ||
            weather1 === "Smoke" ||
            weather1 === "Haze" ||
            weather1 === "Dust" ||
            weather1 === "Fog" ||
            weather1 === "Sand" ||
            weather1 === "Ash" ||
            weather1 === "Squall" ||
            weather1 === "Tornado"
        ) {
            forecastDisplay1.src = `img/cloudy.svg`;
        } else if (weather1 === "Clear") {
            forecastDisplay1.src = `img/clear-${getDayOrNight()}.svg`;
        } else if (weather1 === "Clouds") {
            forecastDisplay1.src = `img/cloudy.svg`;
        }

        if (weather2 === "Thunderstorm") {
            forecastDisplay2.src = `img/thunder.svg`;
        } else if (weather2 === "Drizzle") {
            forecastDisplay.src = `img/drizzle.svg`;
        } else if (weather2 === "Rain") {
            forecastDisplay2.src = `img/rain.svg`;
        } else if (weather2 === "Snow") {
            forecastDisplay2.src = `img/snowy.svg`;
        } else if (
            weather2 === "Mist" ||
            weather2 === "Smoke" ||
            weather2 === "Haze" ||
            weather2 === "Dust" ||
            weather2 === "Fog" ||
            weather2 === "Sand" ||
            weather2 === "Ash" ||
            weather2 === "Squall" ||
            weather2 === "Tornado"
        ) {
            forecastDisplay2.src = `img/cloudy.svg`;
        } else if (weather2 === "Clear") {
            forecastDisplay2.src = `img/clear-${getDayOrNight()}.svg`;
        } else if (weather2 === "Clouds") {
            forecastDisplay2.src = `img/cloudy.svg`;
        }

        if (weather3 === "Thunderstorm") {
            forecastDisplay3.src = `img/thunder.svg`;
        } else if (weather3 === "Drizzle") {
            forecastDisplay3.src = `img/drizzle.svg`;
        } else if (weather3 === "Rain") {
            forecastDisplay3.src = `img/rain.svg`;
        } else if (weather3 === "Snow") {
            forecastDisplay3.src = `img/snowy.svg`;
        } else if (
            weather3 === "Mist" ||
            weather3 === "Smoke" ||
            weather3 === "Haze" ||
            weather3 === "Dust" ||
            weather3 === "Fog" ||
            weather3 === "Sand" ||
            weather3 === "Ash" ||
            weather3 === "Squall" ||
            weather3 === "Tornado"
        ) {
            forecastDisplay3.src = `img/cloudy.svg`;
        } else if (weather3 === "Clear") {
            forecastDisplay3.src = `img/clear-${getDayOrNight()}.svg`;
        } else if (weather3 === "Clouds") {
            forecastDisplay3.src = `img/cloudy.svg`;
        }

        if (weather4 === "Thunderstorm") {
            forecastDisplay4.src = `img/thunder.svg`;
        } else if (weather4 === "Drizzle") {
            forecastDisplay4.src = `img/drizzle.svg`;
        } else if (weather4 === "Rain") {
            forecastDisplay4.src = `img/rain.svg`;
        } else if (weather4 === "Snow") {
            forecastDisplay4.src = `img/snowy.svg`;
        } else if (
            weather4 === "Mist" ||
            weather4 === "Smoke" ||
            weather4 === "Haze" ||
            weather4 === "Dust" ||
            weather4 === "Fog" ||
            weather4 === "Sand" ||
            weather4 === "Ash" ||
            weather4 === "Squall" ||
            weather4 === "Tornado"
        ) {
            forecastDisplay4.src = `img/cloudy.svg`;
        } else if (weather4 === "Clear") {
            forecastDisplay4.src = `img/clear-${getDayOrNight()}.svg`;
        } else if (weather4 === "Clouds") {
            forecastDisplay4.src = `img/cloudy.svg`;
        }
    } catch (e) {
        console.log(e);
    }
};

Why not use a switch statement instead of if/else statements.Its much simpler and a lot less code.https://www.w3schools.com/js/js_switch.asp为什么不使用 switch 语句而不是 if/else 语句。它更简单,代码也更少。https://www.w3schools.com/js/js_switch.asp

I would probably do something like the following.我可能会做类似以下的事情。 Never use variables with the same name and just a number differenciating them, use Arrays or Array-like structures instead so you can loop over them:永远不要使用具有相同名称的变量,并且只使用一个数字来区分它们,而是使用 Arrays 或类似数组的结构,以便您可以循环它们:

// This is not defined in the snippet you showed us, but it makes it easier to loop
const forecastTime = document.querySelectorAll('.forecast-time'),
      forecastDisplay = document.querySelectorAll('.forecast-display');


const res = await axios.get(api);

res.data.list.slice(0, 4) // If there are more than 4, keep the first 4?
  .forEach(({ weather, dt_txt }, i) => {
    forecastTime[i].textContent = dt_txt.substr(11, 15);
    forecastDisplay[i].src = getImageForWeatherType(weather[0].main);
  });



function getImageForWeatherType(type) {
  if (type === "Clear") { return `img/clear-${getDayOrNight()}.svg`; } // Special case

  const imageMap = {
    `img/thunder.svg`: ['Thunderstorm'],
    `img/drizzle.svg`: ['Drizzle'],
    `img/rain.svg`:    ['Rain'],
    `img/snowy.svg`:   ['Snow'],
    `img/cloudy.svg`:  ["Mist", "Smoke", "Haze", "Dust", "Fog", "Sand",
                        "Ash", "Squall", "Tornado", "Clouds"]
  };
  
  return Object.keys(imageMap).find(key => imageMap[key].includes(type));
}

you can use this pattern:你可以使用这个模式:

const getForecast = async (api) => {
    
    const map_weather_img = {
        'Thunderstorm': 'img/thunder.svg',
        'Drizzle': 'img/drizzle.svg',
        'Rain': 'img/rain.svg',
        'Snow': 'img/snowy.svg',
        'Mist': 'img/cloudy.svg',
        'Smoke': 'img/cloudy.svg',
        'Haze': 'img/cloudy.svg',
        'Dust': 'img/cloudy.svg',
        'Fog': 'img/cloudy.svg',
        'Sand': 'img/cloudy.svg',
        'Ash': 'img/cloudy.svg',
        'Squall': 'img/cloudy.svg',
        'Tornado': 'img/cloudy.svg',
        'Clear': `img/clear-${getDayOrNight()}.svg`,
        'Clouds': 'img/cloudy.svg',
    };
    
    try {
        const res = await axios.get(api);
        console.log(res);

        const weather1 = res.data.list[0].weather[0].main;
        const time1 = res.data.list[0].dt_txt.substr(11, 15);
        const weather2 = res.data.list[1].weather[0].main;
        const time2 = res.data.list[1].dt_txt.substr(11, 15);
        const weather3 = res.data.list[2].weather[0].main;
        const time3 = res.data.list[2].dt_txt.substr(11, 15);
        const weather4 = res.data.list[3].weather[0].main;
        const time4 = res.data.list[3].dt_txt.substr(11, 15);

        forecastTime1.textContent = time1;
        forecastTime2.textContent = time2;
        forecastTime3.textContent = time3;
        forecastTime4.textContent = time4;

        forecastDisplay1.src = map_weather_img[weather1];
        forecastDisplay2.src = map_weather_img[weather2];
        forecastDisplay3.src = map_weather_img[weather3];
        forecastDisplay4.src = map_weather_img[weather4];

    } catch (e) {
        console.log(e);
    }
};

but for more flexibility you can use this one:但为了获得更大的灵活性,您可以使用这个:

// array of HTML Element
const forecast = [
    {
        display: /*HTML element*/,
        time: /*HTML element*/,
    },
    {
        display: /*HTML element*/,
        time: /*HTML element*/,
    },
    ...
];

const getForecast = async (api) => {
    
    const table = {
        'Thunderstorm': 'img/thunder.svg',
        'Drizzle': 'img/drizzle.svg',
        'Rain': 'img/rain.svg',
        'Snow': 'img/snowy.svg',
        'Mist': 'img/cloudy.svg',
        'Smoke': 'img/cloudy.svg',
        'Haze': 'img/cloudy.svg',
        'Dust': 'img/cloudy.svg',
        'Fog': 'img/cloudy.svg',
        'Sand': 'img/cloudy.svg',
        'Ash': 'img/cloudy.svg',
        'Squall': 'img/cloudy.svg',
        'Tornado': 'img/cloudy.svg',
        'Clear': `img/clear-${getDayOrNight()}.svg`,
        'Clouds': 'img/cloudy.svg',
    };
    
    try {
        const res = await axios.get(api);
        console.log(res);

        forecast.forEach( (f,i) => {
            const weather = res.data.list[i].weather[0].main;
            const time = res.data.list[i].dt_txt.substr(11, 15);
            f.time.textContent = time;
            f.display.src = table[weather];
        });
        
    } catch (e) {
        console.log(e);
    }
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM