2016-03-01 154 views
2

夥計!Express.js res.render()和res.redirect()

我是Express和Node的新手,我的背景大多是前端,所以這可能是一個困惑的問題。請裸跟我:)

我有我的快遞應用程序,這是應該做的路線如下:

  • 從外部(OK)獲取一些數據
  • 顯示一個HTML與socket.io監聽消息(OK)
  • 執行一些計算,這需要很長的時間
  • 發送消息槽socket.io每一個一個完成(OK)
  • 當所有的計算都完成後頁面,顯示結果LT頁(問題)

所以,我的代碼的簡化版本是:

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

由於這是不行的,我可能想在這裏做一些非常愚蠢的。但是其實我想要做的是:

  • 執行計算
  • 當進行計算,使用套接字
  • 更新進度。當計算完成後,呈現模板,顯示所有的結果。

就是這樣!

我有人有一個更好的(和工作)的解決方案!

乾杯, Hristo。

回答

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> 

希望這是有道理的,有助於...

讓我知道你需要什麼。

玩得開心!

+0

您好,先生,是我的英雄!非常感謝你做的這些! – bitstream

+0

非常歡迎我的朋友。保持良好的工作,真棒! –

+0

雖然有一個問題。當我設置會話變量(session [tadkId])後,當我沒有執行res.send()或類似的事情時,它似乎不是持久的,我不能進入另一邊。否則,它都在工作。我看到其他人有同樣的問題在這裏:http://stackoverflow.com/questions/13426800/express-session-nisting-persisting – bitstream

-1

節點是異步的。使用回調或承諾來確保僅在計算完成時才顯示結果頁面。

+0

Thia已經處理。問題是我無法從相同的路線發送兩次回覆... – bitstream