iT邦幫忙

DAY 28
5

node.js伺服器實戰系列 第 28

node.js伺服器實戰(28) - 進一步釐清伺服器流程

  • 分享至 

  • xImage
  •  

之前的開發比較匆忙,雖然有測試幫助驗證,但是還是需要詳細確認是否有符合需求,並且調整實做程式。
需求

其實需求很簡單,在使用route handler來開發伺服器程式時,伺服器會傳送一個callback,讓使用者把要呈現的畫面render出來:

 .get('/hello', function (request, response, cb) {
     cb(false, '/hello', {
         type: 'text/html',
         data: 'hello'
     });
 })

,而且這個callback需要能多次呼叫,分階段輸出。但是之前在這個callback中,直接觸發了post事件,導致它只能輸出一次,這樣會跟需求不符。所以需要調整。

另外,為了模組化的需求,盡量把這些功能拉到tools.js模組中,這個時候之前沒有分離好的變數就會作怪了。改起來很繁瑣,而且會牽動到每一隻程式,包括測試程式。

還有就是,伺服器使用的流程並不連貫,實體化之後,不能直接方法來加入host/route/fs mapping規則,要先呼叫host(),在一連串規則加入後,才能呼叫listen()。這樣用起來有點不順。

實做

之前的版本已經包裝了response物件,讓tools.serverRender callback輸出時,把資料放進output buffer,直到post dispatch時才把output buffer輸出到瀏覽器。但是callback沒寫好,所以無法多次呼叫。現在加入一個額外參數,決定是否要進入post dispatch。

這樣,在view裡面,就可以根據需求分次輸出:

    "hello_mvc2": function(cb) {
        var view = swig.compileFile('examples/temp3.html');
        var header = swig.compileFile('tests/header.html');
        var footer = swig.compileFile('tests/footer.html');
        this.render = function(data) {
            cb(false, '/hello_mvc2', {type:'text/html', data: header.render(data)});
            cb(false, '/hello_mvc2', {type:'text/html', data: view.render(data)});
            cb(false, '/hello_mvc2', {type:'text/html', data: footer.render(data)}, true);
        };
    }

最後一次輸出時,加上最後一個參數(true),就會把結果輸出到瀏覽器。

route handler的使用現在也可以比較連貫:

 var Evolve = require('../lib/evolve');
 var tools = require('../lib/tools');
 var path = require('path');
 var server = new Evolve({
     dirindex: ['index.html', 'index.htm', 'default.htm']
 })
 .handle('pre',  tools.cookieHandler)
 .host('localhost:8443')
 .map('/', path.join(__dirname, '../www'))
 .get('/hello', function (request, response, cb) {
     cb(false, '/hello', {
         type: 'text/html',
         data: 'hello'
     }, true);
 })
 .get('/hello_mvc', function (request, response, cb) {
     var HelloModel = require('./models')['hello_mvc'];
     var HelloView = require('./views')['hello_mvc'];
     var m = new HelloModel(new HelloView(cb));
     m.execute();
 })
 .get('/hello_mvc1', function (request, response, cb) {
     var HelloModel = require('./models')['hello_mvc1'];
     var HelloView = require('./views')['hello_mvc1'];
     var m = new HelloModel(new HelloView(cb));
     m.execute();
 })
 .get('/hello_mvc2', function (request, response, cb) {
     var HelloModel = require('./models')['hello_mvc2'];
     var HelloView = require('./views')['hello_mvc2'];
     var m = new HelloModel(new HelloView(cb));
     m.execute();
 })
 .listen(8443, 'localhost');

還是需要先呼叫host()再加入route規則,但是可以一次串到底,這樣使用起來就更方便了。

今天的範例檔fillano-evolve-v0.0.21-0-g8637d69.zip,目前版本是v0.0.21。(這次修改的細節相當多,很難把變動的地方都貼上,建議可以用github的diff功能來看改了什麼。)

相關文章


上一篇
node.js伺服器實戰(27) - 整合資料庫引擎
下一篇
node.js伺服器實戰(29) - 簡化非同步操作
系列文
node.js伺服器實戰33
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言