2013-03-22 54 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