【问题标题】:express/node, understanding rendering template and asynchronous modelexpress/node,理解渲染模板和异步模型
【发布时间】:2014-11-24 15:05:44
【问题描述】:

在加载 JSON 和呈现模板方面,我无法理解我的应用程序应该如何正确运行。

想象一下有路由仪表板,我想从外部 API 收集一些数据。我创建了自定义文件(tools.js),我有一个从写入源(https.request(options, function(res)) {...})中获取数据的函数,所以基本上这个过程看起来像:

  1. 我在浏览器中打开我的路由(tools.js 开始从外部 API 收集 JSON)
  2. 模板呈现,tools.js 调用的结果仍未定义
  3. tools.js 刚刚结束加载,在控制台中显示正确的数据,但模板已呈现未定义的结果。

我希望这是有道理的。我明白,这是一种预期的行为,但是在从 tools.js 获取数据后如何“重新渲染”模板?

【问题讨论】:

  • 您需要使用回调函数调用您的工具方法,只有在您获取所有 json 结果后才会继续执行脚本

标签: node.js asynchronous express


【解决方案1】:

您需要在获取数据后呈现您的模板。因此,您等待来自异步数据获取的回调或承诺,并且在该回调中,一旦您拥有数据,您就可以渲染您的模板。

如果您发布代码,我们可以提供更具体的帮助。

节点路由处理程序设计为异步的。在您明确告诉他们您已完成对响应对象的适当函数调用之前,它们不会完成,因此它们可以在您异步获取数据完成后的一段时间后完成,您将数据与模板组合然后告诉你完成的响应对象。

【讨论】:

    【解决方案2】:

    你需要这样做:

    tools.js:

    var https = require('https');
    
    var options = ...
    
    exports.getData = function(cb) {
      var done = false;
      function errorHandler(err) {
        if (!done) {
          done = true;
          cb(err);
        }
      }
      https.request(options, function(res) {
        var buf = '';
        res.setEncoding('utf8');
        res.on('data', function(d) {
          buf += d;
        }).on('end', function() {
          if (!done) {
            done = true;
            var ret;
            try {
              ret = JSON.parse(buf);
            } catch (ex) {
              return errorHandler(ex);
            }
            cb(null, ret);
          }
        }).on('error', errorHandler);
      }).on('error', errorHandler).end();
    };
    

    路线:

    var getData = require('./tools').getData;
    
    // ...
    
    app.get('/json', function(req, res) {
      getData(function(err, data) {
        if (err) return res.send(500);
        res.render('mytemplate', { jsondata: data });
      });
    });
    

    【讨论】:

    • 谢谢@mscdex。现在这对我来说很有意义。如果我想加载多个源怎么办?然后通过遍历这个回调地狱,我只会等待,等待,等待。我想,如果没有更好的方法来做到这一点,并等待这些资源一个接一个地加载,而我的模板仍然会被渲染(有一些空白点,我稍后会在其中加载内容)。这可以通过从客户端调用 AJAX 来实现,但是让节点稍后重新渲染它不是更好的方法吗?我正在考虑类似于meteor.js的概念。
    • 如果您想要执行多个异步任务,例如从多个来源检索数据,您可以考虑使用 async 等模块来帮助组织代码。
    猜你喜欢
    • 2015-07-17
    • 1970-01-01
    • 2015-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-03
    • 1970-01-01
    相关资源
    最近更新 更多