【问题标题】:Express.js res.render() and res.redirect()Express.js res.render() 和 res.redirect()
【发布时间】:2016-06-13 17:36:42
【问题描述】:

我的快递应用中有一条路线,它应该执行以下操作:

  • 从外部获取一些数据(OK)
  • 显示带有 socket.io 监听消息的 HTML 页面(OK)
  • 执行一些需要很长时间的计算
  • 每一个完成后通过socket.io发送一条消息(OK)
  • 所有计算完成后,显示结果页面(问题)

所以,我的代码的简化版本是:

module.exports = function(io) { // This is so I can use socket.io inside the route
  var express = require('express');
  var router = express.Router();

  [... and other required]

  router.post('/', function(req, res, next) {
    res.render('loading'); // This renders the template which holds accepts and renders socket.io messages
    pefromCalculaton();
    sendSocketIOMessage();
    session.data = resultData; // I get the result of all calculations and put that in the session. It's a quick fix, don't judge, I've got no presistancy in my project as for now...
    res.redirect('results'); // And here I'd like to go to the other route, which will display the data, getting it from the session.
  }); 
  return router;
}

由于这不起作用,我可能正在尝试在这里做一些非常愚蠢的事情。但我真正想做的是:

  • 执行计算
  • 在执行计算时,使用套接字更新进度
  • 计算完成后,渲染一个模板,显示所有结果。

【问题讨论】:

    标签: javascript node.js express routes


    【解决方案1】:

    好吧,我的朋友,正如您所知,一个请求中不能发送两个响应。所以这就是你需要做的。

    module.exports = function(io) { // This is so I can use socket.io inside the route
      var express = require('express');
      var router = express.Router();
    
      [... and other required]
    
    router.post('/', function(req, res, next) {
        var taskId = (new Date()).getTime(); //timestamp to get unique task id.
        res.render('loading');
        startCalculations(function(progressIndicator){  //progress callback
             io.emit('progress',progressIndicator);
        },function(result){  // Finish callback
             session[taskId] = result;
             io.emit('finish',{ taskid: taskId });
        });
    });
    
    
    router.get('/result:taskId', function(req, res, next) {
        var result = session[req.params.taskId];
        if(!result)
        {
           //Result already consumed!
           res.render('expired');
           return;
        }
        delete session[req.params.taskId];
        res.render('result', {result: result});
    });
    
     //progress callback will be called when we want to report progress
     //done callback indicates our results are ready.
    function startCalculations(progress, done){
        //This is just a stupid piece of code, just to emulate loading.
        //Your awesome async code will replace this
        //In your case it will not be a loop and there will be a callback
        //To signal finish.
        var result = 0;
        for(i = 0; i < 100; i++)
        {
             result = result + i;
             //Simulate progress
             progress(i);
        }
        //Simulate finish -- result has 0 to 99 all added up ;)
        done(result);
    
    }
    
    
    return router;
    }
    

    现在在 html 前端你可以拥有 ...

    这就是您的loading 视图的样子。

    <script src="/socket.io/socket.io.js"></script>
    <script src="http://code.jquery.com/jquery-1.11.1.js"></script>
    <script>
      var socket = io();
    
     //Init code.
    
      socket.on('progress', function(progressIndicator){
        //Your jquery mojo to show progress
        displayProgress(progressIndicator);
      });
    
      socket.on('finish', function(task){
        //Redirect to result page from frontend (you were trying to do
        //on backend -- node.js)
        window.location.href = "/result/" + task.taskId;
        //OR
        //window.location.replace("/result/" + task.taskId);
      });
    </script>
    

    希望这是有道理的并有所帮助...

    如果您还需要什么,请告诉我。

    玩得开心!

    【讨论】:

    • 您,先生,是我的英雄!非常感谢您!
    • 不客气,我的朋友。继续努力,变得很棒!
    • 不过有一个问题。当我在设置会话变量 (session[tadkId]) 后不执行 res.send() 或类似操作时,它似乎没有持续存在,我无法进入另一端。否则一切正常。我在这里看到其他人也有同样的问题:stackoverflow.com/questions/13426800/…
    • 好的,修好了!我必须做的是在我设置 req.session.taskId 后调用 req.session.save() :)
    【解决方案2】:

    节点是异步的。使用回调或承诺确保仅在计算完成后显示结果页面。

    【讨论】:

    • Thia 已被处理。问题是我不能从同一条路由发送两次响应...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多