【问题标题】:Using the results of a GET request in Express router在 Express 路由器中使用 GET 请求的结果
【发布时间】:2017-02-02 07:09:22
【问题描述】:

第一个 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 中可用,但是浏览器窗口挂起并且 @ 987654325@ 部分永远无法到达。

我知道只有在端点数据请求完成后才应该进行渲染(async.series 用法),但我似乎对如何实际使用 main 中的 getFinhockeyData 函数的结果数据缺乏基本的了解路线。

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

【问题讨论】:

    标签: javascript node.js express routing html-rendering


    【解决方案1】:

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

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

    【讨论】:

    • 这似乎有效。非常感谢!我现在将继续与 Pug 模板搏斗。
    【解决方案2】:

    您正在响应您的路由调用

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

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

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

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

    【讨论】:

      【解决方案3】:

      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] });
               }
              })
      });
      

      【讨论】:

        猜你喜欢
        • 2016-08-08
        • 2018-09-10
        • 2021-02-11
        • 2018-05-26
        • 2018-08-25
        • 2013-06-12
        • 1970-01-01
        • 1970-01-01
        • 2017-05-14
        相关资源
        最近更新 更多