在 Express 路由器中使用 GET 请求的结果

Using the results of a GET request in Express router

第一个 Node/Express 应用程序。

我很难思考如何从端点检索数据并将其呈现在浏览器中。

我有一个 dataservice.js 从这样的端点获取一个 JSON 对象:

const http = require('http');

getFinhockeyData = function() {

    http.get('http://tilastopalvelu.fi/ih/modules/mod_standings/helper/standings.php?statgroupid=3545', (res) => {
      console.log(`Got response: ${res.statusCode}`);

      var body = "";

      res.on('data', function (chunk) {
        body += chunk;
    })

      res.on('end', function () {
        var data = JSON.parse(body);
        console.log('data parsed.');
        console.log('first team name: ' + data.teams[0].TeamName);
        console.log(typeof data);
        return data;
    })

    }).on('error', (e) => {
      console.log(`Got error from Finhockey: ${e.message}`);
    });
}

module.exports.getFinhockeyData = getFinhockeyData;

到目前为止一切正常,data 对象可以 console.logged 并且其内容可用。

router.js 目前看起来像这样:

'use strict';

const express = require('express');
const async = require('async');
const router = express.Router();
const dataservice = require('./dataservice.js')


router.get('/', function(req, res) {
    async.series([
            function(callback) {
                getFinhockeyData(callback)
            }
        ],
        function(err, results) {
            console.log('start rendering');
            res.render('index', { data: data });
        })
});

module.exports = router;

当我 运行 应用程序并刷新 / 路由时,我可以从控制台看到 getFinhockeyData 被调用并且数据对象的内容在 dataservice.js 中可用console.logs,但浏览器 window 挂起,res.render 部分从未到达。

我知道渲染应该只在端点数据请求完成后完成(async.series 用法),但我似乎对如何实际使用来自 getFinhockeyData 的结果数据缺乏基本的了解在主要路线上发挥作用。

对此有何建议?如有必要,我很乐意提供更多信息。

首先,执行请求是异步的,因此您必须使用回调或承诺。
即使是异步中间件也不会让你只 return 来自异步调用的数据,它需要一个回调,但在这里使用原生承诺似乎更容易

const http = require('http');

getFinhockeyData = function() {
  return new Promise( (resolve, reject) => {
    http.get('http://tilastopalvelu.fi/ih/modules/mod_standings/helper/standings.php?statgroupid=3545', (res) => {
      var body = "";

      res.on('data', function(chunk) {
        body += chunk;
      });

      res.on('end', function() {
        resolve( JSON.parse(body) );
      });

    }).on('error', reject);
  });
}

module.exports.getFinhockeyData = getFinhockeyData;

另请注意,您要导出为带有 属性

的模块
module.exports.getFinhockeyData = getFinhockeyData;

当你要在路线中使用它时,你必须使用 属性

const dataservice = require('./dataservice.js');

router.get('/', function(req, res) {
    dataservice.getFinhockeyData().then(function(data) {
        res.render('index', { data: JSON.stringify(data) }); 
    }).catch(function(err) {
        // epic fail, handle error here
    });
});

您正在通过

回复您的路线呼叫
res.render('index', { data: data });

但是没有数据变量。应该是

res.render('index', { data: results });

当数据来自回调时,您存储数据的变量是什么

res.render() 没有被调用的原因是,http 请求是异步的。要获得响应,必须传递回调,您这样做了但忘记在 dataservice.js

中调用它

这应该有帮助...

像下面这样改变你的dataservice.js...

const http = require('http');

getFinhockeyData = function(callback) {

    http.get('http://tilastopalvelu.fi/ih/modules/mod_standings/helper/standings.php?statgroupid=3545', (res) => {
      console.log(`Got response: ${res.statusCode}`);

      var body = "";

      res.on('data', function (chunk) {
        body += chunk;
    })

      res.on('end', function () {
        var data = JSON.parse(body);
        console.log('data parsed.');
        console.log('first team name: ' + data.teams[0].TeamName);
        console.log(typeof data);
        callback(null, data); //returning the data to the callback
    })

    }).on('error', (e) => {
      console.log(`Got error from Finhockey: ${e.message}`);
      callback(e, null); 
    });
}

module.exports.getFinhockeyData = getFinhockeyData;

像下面这样改变你的router.js...

router.get('/', function(req, res) {
    async.series([
            function(callback) {
                getFinhockeyData(callback)
            }
        ],
        function(err, results) {
         if(err === null){
            console.log('start rendering');
            res.render('index', { data: results[0] });
         }
        })
});