JavaScript:捕获异步函数中的错误,如果有任何其他函数,则停止该函数的其余部分

时间:2019-07-11 23:22:03

标签: javascript async-await

编辑:下面的答案

我正在制作我的第一个JavaScript项目,并决定制作一个简单的Weather应用程序。它从openweathermap.org api中获取您放入的城市的天气数据,并将其显示在表格中。我首先使用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 :(得分:0)

您可以这样做:

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();

答案 1 :(得分:0)

实际上,捕获到的错误不是api本身的错误,因为api仍会发送json,但是在尝试从json读取某个对象时捕获了该错误(因为json是不是具有天气数据的正常人)。因此,在使表格可见之后,该功能的停止时间比预期的要晚得多。

我只是将使表格可见的行放在创建表格的函数之后(发生实际错误之后)。也感谢@Dadboz的try catch方法,它使代码更加紧凑。我还添加了if,以检查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"; 
}

感谢大家的回答,祝您有美好的一天!

洛伦佐