Node JS等待启动从数据库初始化的最佳方式等

我知道节点是非阻塞等,但我不知道如何解决这个问题没有阻塞。

你启动服务器

node app.js 

但是在处理传入的请求之前,您需要从数据库或MongoDB中configuration一些configuration等,因此您需要等待数据库响应在启动之前返回,以处理请求。

我可以使用灵活的,但是你必须包裹路线等全部在第二个执行块是讨厌的。

最好的办法是什么?

节点确实是非阻塞的,但这并不意味着您需要立即开始接受请求! 看一下经典的HTTP服务器的例子:

 var http = require('http'); var server = http.createServer(function (req, res) { // ... logic to handle requests ... }); server.listen(8000); 

在调用server.listen之前,你可以做任何你喜欢的事情,包括你需要的任何configuration任务。 假设这些任务是asynchronous的,您可以在callback中启动服务器:

 var http = require('http'); var server = http.createServer(function (req, res) { // ... logic to handle requests ... }); // Set up your mongo DB and grab a collection, and then... myMongoCollection.find().toArray(function(err, results) { // Do something with results here... // Then start the server server.listen(8000); }); 

阻止必要的事情是可以的。 不要为了它而去asynchronous!

在这种情况下,由于数据库对于您的应用程序甚至是运行至关重要,因此阻塞直到准备就绪为止(并且可能为您节省了很多处理没有连接数据库的调用的麻烦)。

您也可以推迟启动您的应用程序服务器(在callback,承诺等),直到调用启动数据库完成。 虽然在应用程序初始化之前没有其他事情发生(从我在问题中可以看出来的情况),但这两种方法都无关紧要,因为您不会从其他任何方面窃取单线程!

基于server.listenangular色的意义,我使用的顺序灵活,做了以下….

在第一个块中,我从db(在这个例子中是弹性search)中得到了一些东西,然后对它进行一些操作,在第二个块中构build路由,然后在最后一个块中启动服务器。 你可以使用灵活的做一些其他的初始化任务,只是在第一个串行块内做一个并行块。

 var chans = []; flow.series([ function (cb) { esClient.search({ ... }).then(function (resp) { var channels = resp.hits.hits; channels.forEach(function(chan){chans.push(chan.urlSlug)}); chans = chans.join('|'); cb(); }); }, function(cb) { app.get('/:type('+types+')/[az\-]+/[a-z0-9\-]+-:id/', itemRt.feature);//http://localhost:3000/how-to/apple/apple-tv-set-up-tips-3502783/ app.get('/:urlSlug('+types+')/', listingRt.category); app.get('/:urlSlug('+chans+')/', listingRt.channel); cb(); }, function(cb) { server.listen(app.get('port'), function(){ console.log('Express server listening on port ' + app.get('port')); cb(); }); } ]);