iT邦幫忙

DAY 22
5

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

Node.js伺服器實戰(22) - 細部調整

  • 分享至 

  • xImage
  •  

之前只用event機制來實做流程,會有控制不夠精確的問題,所以再來改一下。
問題

之前的流程修改雖然通過測試,但是總覺得還沒有兼顧到夠完整的狀況,所以需要在仔細分析一下需求。

調整

流程的修改大概如下:

  1. 需要有一個「預設」的pre dispatch,並且在裡面trigger dispatch事件
  2. 所有的pre dispatch handler跑完後,如果沒有進入自訂的dispatch過程,才會進入上述dispatch流程
  3. 在dispatch流程最後,trigger post dispatch流程

但是要兼顧到非同步執行...又要在適當時機trigger下一個流程,做法會有點複雜,需要有一個方法等待處理結束,然後再處理結束時,觸發下一個流程。這個時候單靠簡單的Javascript有點難控制,需要用額外的方法來處理。

實做

先加入一個wait函數,長這樣:

 var wait = function(callbacks, req, res, done) {
     var counter = callbacks.length;
     var results = [];
     var next = function(result) {
       results.push(result);
         if(--counter < 1) {
             done(results);
         }
     };
     if(counter === 0) {
         done(results);
         return;
     }
     for(var i = 0; i < callbacks.length; i++) {
         callbacks[i](req, res, next);
     }
 };

然後執行傳入的callbacks(也就是handlers),全部執行結束時,才觸發dispatch事件。dispatch事件會監看一個flag變數:dispatched,如果已經觸發過就不會再執行一次。這樣可以保證在header中觸發的dispatch不會再次執行。

不過在handler的定義中,除了傳給它request, response參數,還必須傳next這個callback,讓他在執行完畢後呼叫。

    "cookieHandler": function(request, response, next) {
        if(request.headers.cookie) {
            request.cookie = tools.cookieParser(request.headers.cookie);
        } else {
            request.cookie = {};
        }
        next();
    }

伺服器的主程式調整成這樣:

 var http = require('http'),
     tools = require('./tools');
 
 var count = 0;
 
 var wait = function(callbacks, req, res, done) {
     var counter = callbacks.length;
     var results = [];
     var next = function(result) {
       results.push(result);
         if(--counter < 1) {
             done(results);
         }
     };
     if(counter === 0) {
         done(results);
         return;
     }
     for(var i = 0; i < callbacks.length; i++) {
         callbacks[i](req, res, next);
     }
 };
 
 module.exports = function(conf) {
     var pre = [];
     var server = http.createServer(function(request, response) {
         var dispatched = false;
         var post = false;
         var precount = 0;
         
         //tools.cookieHandler(request, response);
         console.log(process.pid + '::' + (++count) + ': ' + process.memoryUsage().heapUsed);
         //this.emit('pre', request, response);
         wait(pre, request, response, function(){
             server.emit('dispatch', conf, request, response, function(err, realpath, data) {
                 if(dispatched) {
                     return;
                 } else {
                     dispatched = true;
                 }
                 if(err) {
                     console.log(process.pid + '::' + realpath + ' not exists.');
                     response.writeHead(404, {"Content-Type":"text/html"});
                     response.end('<h1>404: Request resource not found.</h1>');
                 } else {
                    console.log(process.pid + '::' + realpath + ' exists.');
                    response.writeHead(200, {
                        "Content-Type": data.type,
                        "Content-Length": data.data.length
                    });
                    response.end(data.data);
                 }
                 server.emit('post', request, response);
             });
         });
     });
     this.listen = function(port, addr) {
         server.listen(port, addr);
         return this;
     };
     this.close = function() {
         server.close();
         return this;
     };
     this.host = tools.hostHandler;
     this.handle = function(hook, handler) {
         switch(hook) {
             case 'pre':
                 pre.push(handler);
                 break;
             case 'dispatch':
                 server.on('dispatch', handler);
                 break;
             case 'post':
                 server.on('post', handler);
         }
     };
     this.handle('dispatch', tools.dispatch);
 };

跑一下整合測試,可以通過,應該OK了吧?碰到問題再來調整好了,目前還沒有足夠的pre dispatch handler可以測試。

今天的範例檔fillano-evolve-v0.0.16-0-g0438ff0.zip,目前版本是v0.0.16。

相關文章


上一篇
node.js伺服器實戰(21) - 建構伺服器流程
下一篇
node.js伺服器實戰(23) - 考慮MVC
系列文
node.js伺服器實戰33
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言