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

伙计们!

我是Express和Node的新手,我的背景大多是前端,所以这可能是一个困惑的问题。 请和我裸着:)

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

  • 从外面获取一些数据(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; } 

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

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

而已!

我有人有一个更好的(和工作)的解决scheme!

干杯,Hristo。

那么,我的朋友,你知道一个请求中不能发送两个响应。 所以这里是你需要做的。

 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> 

希望这是有道理的,并帮助…

需要帮助请叫我。

玩的开心!

节点是asynchronous的。 使用callback或承诺确保只有在计算完成时才显示结果页面。