编辑:下面的答案
我正在制作我的第一个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
谢谢
答案 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";
}
感谢大家的回答,祝您有美好的一天!
洛伦佐