2013-03-22 55 views
7

我爲Connect和Express編寫了一箇中間件,它需要一些繁重的安裝方法。由於初始化任務的性質,這些東西是異步的,所以我有一個問題,即中間件只能在初始化運行後才能訪問。如何在Connect中間件中使用異步初始化?

目前我一直在使用一個回調解決了這個問題:

function setupMiddleware(callback) { 
    doSomeAsyncInitialization(function() { 
    callback(function (req, res, next) { 
     // The actual middleware goes here ... 
    }); 
    }); 
} 

這工作,但它不是主叫不錯。而不是能夠做

app.use(setupMiddleware()); 

我必須做的:

setupMiddleware(functin (middleware) { 
    app.use(middleware); 
}); 

現在我在想是否有更好的方法,例如讓中間件在後臺初始化並延遲所有傳入請求,直到中間件準備就緒。

我該如何解決這個問題?我應該在這裏使用的任何想法或最佳實踐?

回答

2

我現在解決它使用isInitialized變量和延遲中間件功能本身。請看下面的例子:

var connect = require('connect'); 

var setup = function() { 
    var isInitialized = false; 

    setTimeout(function() { 
    isInitialized = true; 
    }, 10000); 

    function run (req, res, next) { 
    res.write('Foo'); 
    res.end(); 
    } 

    function delay (req, res, next) { 
    if (isInitialized) { 
     return run(req, res, next); 
    } 

    setTimeout(function() { 
     delay(req, res, next); 
    }, 1000); 
    } 

    return function (req, res, next) { 
    if (req.url === '/foo') { 
     delay(req, res, next); 
     return; 
    } 
    next(); 
    } 
}; 

var app = connect(); 
app.use(setup()); 
app.use(function (req, res) { 
    res.write('Fertig!'); 
    res.end(); 
}); 

var http = require('http'); 

http.createServer(app).listen(5000); 

請注意,此代碼沒有優化或以任何方式重構,它僅僅是這個想法本身工作的示範。

0

爲什麼你不這樣做像下面這樣

doSomeAsyncInitialization(function() { 
    //After doing all long running init process just configure your express as follows. 
    app.use(<middlewares>); 
    app.listen(<portnumder>); 

}); 
+1

因爲初始化只適用於一箇中間件,而不適用於整個應用程序。這種模式當然有用,但它不是「好」的。我不喜歡所有內容都縮進一步(這不僅僅是一個格式問題;-))。 – 2013-03-22 13:27:50

+0

我接受它。由於Nodejs是非阻塞的,因此您必須在長時間運行的進程回調中或按照問題中顯示的方式獲取代碼。 Ofcource,你可以使用一些異步模塊。在這裏,我假設你的中間件對所有請求都是強制的,這樣你就可以保存在app.use()函數中。我的建議是,您只需在開始監聽端口之前初始化中間件。如果您期待的不僅僅是格式化,我還需要了解「doSomeAsyncInitialization」功能正在發生什麼。 – 2013-03-22 13:58:33

+0

那麼,正如所說的,一個想法可能是設置函數立即返回中間件,但中間件會延遲傳入的請求,直到它完全初始化。 – 2013-03-22 14:27:43