javascript - 如何使用express和node进行异步调用

标签 javascript node.js ajax express asynchronous

我有一个小型应用程序,它询问用户他们的城市并返回当前的天气数据。当用户单击“获取天气”功能时,它会从 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 }`))

weatherFunctions.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) 。您可以使用名为 fetch 的 XHR 包装器这使得使用 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>

关于javascript - 如何使用express和node进行异步调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59228892/

相关文章:

javascript - html5 Canvas 图像移动问题

javascript - 清除不同表上的匹配单元格(无序列)

node.js - sequelize index 选项运行两次并导致测试失败

javascript - 从服务器向客户端发送消息socket.io

javascript - AngularJS $http 返回值

javascript - Ajax 不向同一端口上的本地主机发送请求

javascript - Angular2 条件表单验证器

javascript - 如何在javascript中使用动态golang html模板id?

node.js - 如何使用 nodejs 提供图像

PHP 不插入 SQL 列