JavaScript: перехват ошибок в асинхронной функции и остановка остальной функции, если есть - PullRequest
0 голосов
/ 12 июля 2019

РЕДАКТИРОВАТЬ: ОТВЕТИТЬ НИЖЕ

Я делаю свой первый JavaScript-проект и решил создать простое приложение погоды. Он извлекает данные о погоде для города, который вы указали, из API openweathermap.org и отображает их в виде таблицы. Сначала я сделал это с помощью fetch () и .then. Затем я узнал об асинхронных функциях и ключевом слове await. После преобразования скрипта в асинхронную функцию я столкнулся с проблемой. Если первый город, который вы вводите, не является реальным городом (при извлечении API-кода обнаруживается ошибка), появляется предупреждающее сообщение, НО таблица также появляется, потому что остальная часть функции все еще выполняется. Итак, мой вопрос: как я могу остановить асинхронную функцию, если какие-либо ошибки перехвачены?

Вот сайт: https://lorenzo3117.github.io/weather-app/

Вот код:

// Launch weather() function and catch any errors with the api request and display the warning message if there are any errors
function main() {
    weather().catch(error => {
        document.querySelector("#warningMessage").style.display = "block";
        console.log(error);
    });
}

// Main function
async function weather() {

    // Take city from input and reset input field
    var city = document.querySelector("#cityInput").value;
    document.querySelector("#cityInput").value = "";

    // Get api response and make it into a Json
    const apiResponse = await fetch("https://api.openweathermap.org/data/2.5/weather?q=" + city + "&appid=<apiKey>&units=metric");
    const jsonData = await apiResponse.json();

    // Removes warning message
    document.querySelector("#warningMessage").style.display = "none";

    // Puts the Json into an array and launches createTable function
    var arrayJson = [jsonData];
    createTable(document.querySelector("#table"), arrayJson);

    // Function to create the table
    function createTable(table, data) {
        // Makes the table visible
        document.querySelector("#table").style.display = "block";

        // Goes through the array and makes the rows for the table
        for (let i = 0; i < data.length; i++) {
            let rowData = data[i];
            var row = table.insertRow(table.rows.length);

            // This var exists to make the first letter capitalized without making a gigantic line (see insertCell(3), line 53)
            // Could be made into a function if needed
            var weatherDescription = rowData.weather[0].description;

            // Take latitude and longitude for google maps link
            var lat = rowData.coord.lat;
            var long = rowData.coord.lon;
            // Make an a-tag for link to google maps
            var mapLink = document.createElement("a");
            mapLink.innerHTML = "Link";
            mapLink.target = "_blank";
            mapLink.href = "https://www.google.com/maps/search/?api=1&query=" + lat + "," + long;

            // Making rows in table
            row.insertCell(0).innerHTML = rowData.name + ", " + rowData.sys.country;
            row.insertCell(1).innerHTML = rowData.main.temp + " °C";
            row.insertCell(2).innerHTML = rowData.main.humidity + "%";
            row.insertCell(3).innerHTML = weatherDescription.charAt(0).toUpperCase() + weatherDescription.slice(1);
            row.insertCell(4).appendChild(mapLink); // appendChild for anchor tag because innerHTML only works with text
        }
    }

И репо: https://github.com/lorenzo3117/weather-app

Спасибо

Ответы [ 2 ]

0 голосов
/ 12 июля 2019

На самом деле, пойманная ошибка не является ошибкой самого API, потому что API все еще отправляет JSON, но ошибка ловится при попытке прочитать определенный объект из JSON (который не существует, потому что JSON не не нормальный с погодными данными). Поэтому функция останавливается намного позже, чем ожидалось, после того, как таблица стала видимой.

Я просто поместил строку, которая сделала таблицу видимой после функции, которая создает таблицу (после того, где происходит настоящая ошибка). Также спасибо @Dadboz за метод try catch, который сделал код еще более компактным. Я также добавил if else, чтобы проверить, является ли файл json правильным, чтобы ненужный код не выполнялся. Спасибо @James за то, что указал мне на это.

Вот окончательный код:

// Main function
async function weather() {
    try {
        // Take city from input and reset input field
        var city = document.querySelector("#cityInput").value;
        document.querySelector("#cityInput").value = "";

        // Get api response and make it into a Json
        const apiResponse = await fetch("https://api.openweathermap.org/data/2.5/weather?q=" + city + "&appid=<apiKey>&units=metric");
        const jsonData = await apiResponse.json();

        if (jsonData.message == "city not found") {
            document.querySelector("#warningMessage").style.display = "block";
        } else {
            // Removes warning message
            document.querySelector("#warningMessage").style.display = "none";

            // Puts the Json into an array and launches updateTable function
            var arrayJson = [jsonData];
            updateTable(document.querySelector("#table"), arrayJson);         
        }
    }

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

// Function to update the table
function updateTable(table, data) {

    // Goes through the array and makes the rows for the table
    for (let i = 0; i < data.length; i++) {
        let rowData = data[i];
        var row = table.insertRow(table.rows.length);

        // This var exists to make the first letter capitalized without making a gigantic line (see insertCell(3), line 53)
        // Could be made into a function if needed
        var weatherDescription = rowData.weather[0].description;

        // Take latitude and longitude for google maps link
        var lat = rowData.coord.lat;
        var long = rowData.coord.lon;
        // Make an a-tag for link to google maps
        var mapLink = document.createElement("a");
        mapLink.innerHTML = "Link";
        mapLink.target = "_blank";
        mapLink.href = "https://www.google.com/maps/search/?api=1&query=" + lat + "," + long;

        // Making rows in table
        row.insertCell(0).innerHTML = rowData.name + ", " + rowData.sys.country;
        row.insertCell(1).innerHTML = rowData.main.temp + " °C";
        row.insertCell(2).innerHTML = rowData.main.humidity + "%";
        row.insertCell(3).innerHTML = weatherDescription.charAt(0).toUpperCase() + weatherDescription.slice(1);
        row.insertCell(4).appendChild(mapLink); // appendChild for anchor tag because innerHTML only works with text
    }

    // Makes the table visible
    document.querySelector("#table").style.display = "block"; 
}

Спасибо всем за ваши ответы, хорошего дня!

Lorenzo

0 голосов
/ 12 июля 2019

вы можете сделать это:

async function weather() {
  try {
     const apiResponse = await fetch("https://api.openweathermap.org/data/2.5/weather?q=" + city + "&appid=02587cc48685af80ea225c1601e4f792&units=metric");
  } catch(err) {
     alert(err); // TypeError: failed to fetch
     return;
   } 
}

 weather();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...