Express.js res.render()和res.redirect()

时间:2016-03-01 10:35:21

标签: javascript node.js express routes

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

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

因此,我的代码的简化版本是:

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

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

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

2 个答案:

答案 0 :(得分:2)

好吧,我的朋友,因为你知道一个人不能在一个请求中发送两个回复。所以这就是你需要做的。

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>

希望这有意义并有所帮助......

如果您还有其他需要,请告诉我。

玩得开心!

答案 1 :(得分:-1)

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