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

只愿长相守 提交于 2019-12-06 06:55:16

Well, my friend, as you know that one can't send two responses from within one request. So here is what you need to do.

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

Now on the html front you can have ...

this is how your loading view would look like.

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

Hope this makes sense and helps ...

Let me know if you need anything else.

Have fun!

Node is asynchronous. Use callbacks or promises to make sure that the result page is shown only when the calculations has been completed.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!