javascript - 如何使用 express 和 node 进行异步调用
问题描述
我有一个小应用程序,它询问用户他们的城市并返回当前的天气数据。当用户单击“获取天气”功能时,它会从 OpenWeatherMap api 中提取 Json 并将其返回给用户。截至目前,它刷新页面并显示数据。我需要更改什么,以便在您更改城市时异步加载而不是刷新页面?
Server.js(快速路由)
const express = require('express');
const bodyParser = require('body-parser');
const weatherFunctions = require('./functions/weatherFunctions.js')
const PORT = process.env.PORT || 5000
const app = express()
app.use(express.static('public'));
app.use(bodyParser.urlencoded({ extended: true }));
app.set('view engine', 'ejs')
app.get('/', (req, res) => {
res.render('index', {weather: null, error: null});
})
app.post('/', weatherFunctions.getWeather)
app.listen(PORT, () => console.log(`Listening on ${ PORT }`))
天气函数.js
const request = require('request');
const apiKey = '28af81603ac21f0fe4c75478dad21818';
function currentWeather(req, res) {
let city = req.body.city;
let url = `http://api.openweathermap.org/data/2.5/weather?q=${city}&units=imperial&appid=${apiKey}`
request(url, function (err, response, body) {
if (err) {
res.render('index', {
weather: null,
error: 'Error, please try again'
});
} else {
let weather = JSON.parse(body)
if (weather.main == undefined) {
res.render('index', {
weather: null,
error: 'Error, please try again'
});
} else {
let weatherText = `It's ${weather.main.temp} degrees in ${weather.name}! `;
weatherText += `The low for today will be ${weather.main.temp_min} degrees with a high of ${weather.main.temp_max}`;
res.render('index', {
weather: weatherText,
error: null
}); //passes parameters for ejs to read
}
}
});
}
module.exports = {
getWeather: currentWeather
};
索引.ejs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Simple Weather</title>
<link rel="stylesheet" type="text/css" href="/css/style.css">
<link href='https://fonts.googleapis.com/css?family=Open+Sans:300' rel='stylesheet' type='text/css'>
</head>
<body>
<div class="container">
<fieldset>
<form action="/" method="post">
<input name="city" type="text" class="ghost-input" placeholder="Enter a City" required>
<input type="submit" class="ghost-button" value="Get Weather">
</form>
<% if(weather !== null){ %>
<p><%= weather %></p>
<% } %>
<% if(error !== null){ %>
<p><%= error %></p>
<% } %>
</fieldset>
</div>
</body>
</html>
解决方案
它让您耳目一新的原因是因为您正在渲染 HTML 服务器端。您将需要利用XMLHttpRequest (aka XHR)。您可以使用一个名为 XHR 的包装器fetch
,这使得使用 XHR 变得更加容易。
使用浏览器获取 API 数据,然后使用该数据修改 DOM,称为“客户端渲染”。
例如,如果您打开浏览器控制台,并将以下代码粘贴到其中,您将看到如何从浏览器发送请求并取回数据(这是客户端渲染的基础):
fetch(`https://api.openweathermap.org/data/2.5/weather?q=New York&units=imperial&appid=28af81603ac21f0fe4c75478dad21818`).then(res => res.json()).then(data => console.log(data));
请参见以下示例:
document
.getElementById("getWeather")
.addEventListener("click", () => {
handleGetWeather();
});
async function handleGetWeather() {
const apiKey = "28af81603ac21f0fe4c75478dad21818";
const locationEl = document.getElementById("location");
const weatherDataEl = document.getElementById("weatherData");
const results = await currentWeather(locationEl.value, apiKey);
weatherDataEl.innerHTML = results;
}
async function currentWeather(location, apiKey) {
const city = location.replace(/\s\s+/g, ' '); // Replace multiple spaces with single space
if (city === "" || city === " ") return `<pre>Please enter a location!</pre>`;
let url = `https://api.openweathermap.org/data/2.5/weather?q=${city}&units=imperial&appid=${apiKey}`;
try {
const res = await fetch(url);
if (res.ok === false) {
return `<pre><i>Location '${encodeURIComponent(city)}' not found!</i></pre><br/><pre>Full Error: ${res.statusText}</pre>`;
}
const weather = await res.json();
const main = weather.main;
const t = Number(main.temp) >= 71.00 ? 'hot' : 'cold';
const min = Number(main.temp_min) >= 71.00 ? 'hot' : 'cold';
const max = Number(main.temp_max) >= 71.00 ? 'hot' : 'cold';
return `
<h1>
It's <span class="${t}">${main.temp}</span> degrees in ${weather.name}!
</h1>
<h1>
The low for today will be
<span class="${min}">${main.temp_min}</span>
degrees with a high of
<span class="${max}">${main.temp_max}</span>
</h1>
`;
} catch {
return `<pre><i>Error, please try again.</i></pre>`;
}
}
pre {
color: red;
margin-bottom: -15px;
}
.hot {
color: red;
}
.cold {
color: blue;
}
<input id="location" />
<button id="getWeather">Get Weather</button>
<div id="weatherData"></div>
推荐阅读
- c++ - 现代 Opengl glimagesink 示例
- adb - avd 无法正常工作,无法找到 adb,重新安装 sdk,设置环境路径,在 cmd 中给出上述消息。这一切都说了什么
- c++ - 数组表现为变量
- flutter - 如何在更改滑动条中的值的函数中执行写入方法?
- c - C.Launch 的 VS Code 调试问题
在 launch.json 中不存在 - curl - 卷曲问题 NSS 错误 -5961 (PR_CONNECT_RESET_ERROR)
- r - 我需要过滤数据而不丢失信息,它是字符但我无法过滤它
- rest - 如何对 Tableau 进行 REST 调用
- solidity - 如何为每场比赛智能合约添加平仓和开仓功能?
- python - 我无法使用 discord.py 向任何人添加角色