快递中间件下一期

时间:2013-08-29 17:17:29

标签: javascript node.js express middleware

我不清楚如何顺序调用Express中间件。我希望下一个中间件只在上一个中间件完成后才会发生。我认为我必须调用next()才能实现它,但事实并非如此。

mongoose.connect(app.set("db-uri"));

app.use(function(req, res, next) {
 if(1 !== mongoose.connection.readyState) {
    console.log('Database not connected');
    res.render("system/maintenance", {
      status: 500
    });
  } else {
    return next();
  }
});


// This middleware does not wait for the previous next(). It just tries to connect before actually.
app.use(express.session({
  secret: settings.sessionSecret,
  maxAge: new Date(Date.now() + 3600000),
  store: new MongoStore({ mongoose_connection: mongoose.connections[0], auto_reconnect: true })
}));

编辑:更新代码,仅在中间件启动和检查状态时连接Mongoose

2 个答案:

答案 0 :(得分:1)

我承认这不是一个非常完整的答案,更不用说测试了,但它的要点应该有效。

首先,在启动应用程序时连接数据库,例如不在中间件中。只需将moongoose.connect内容放在app.use之外的某处(参见任何mongoose + express示例,如this one)。

其次,我会使用一个“标志”来跟踪猫鼬是否已断开连接。

var mongooseIsConnected = false;

mongoose.on('open', function () {
  mongooseIsConnected = true;
});

mongoose.on('error', function () {
  mongooseIsConnected = false;
});

请注意,这是一个很大的猜测。我不知道错误事件是否仅在连接失败时触发,同样我不知道重新连接时是否会打开“open”。如果您在某些文档中发现,请告诉我,我会更新此答案。

最后,在使用数据库的任何其他中间件之前放置一个中间件是直截了当的 - 它检查标志是真还是假并且传递请求或者呈现错误。

app.use(function (req, res, next) {
  if(mongooseIsConnected) {
    next();
  }
  else {
    res.status(500);
    res.render('errorView');
    // Or you could call next(new Error('The database is broken')); and handle 
    // the error in a central express errorHandler
  }
});

// app.use(express.session etc here...

更新,这是一个在打开之前不使用mongoose连接的解决方案:

mongoose.connect('uri...', configureApp);

function configureApp () {
  app.use(express.session({
    secret: settings.sessionSecret,
    maxAge: new Date(Date.now() + 3600000),
    store: new MongoStore({ mongoose_connection: mongoose.connections[0], auto_reconnect: true })
  }));

  // The other middleware and app.listen etc
}

这应该确保在定义中间件之前建立连接。然而,在挖掘我自己的代码时,我发现我只是让MongoStore创建一个新连接。这可能更容易。

答案 1 :(得分:0)

好的,这似乎有效。在这里公开评论问题。

var store;
mongoose.connect(app.set("db-uri"));
mongoose.connection.on("connect", function(err) {
  // Create session store connection
  store = new MongoStore({ mongoose_connection: mongoose.connections[0], auto_reconnect: true });
});


app.use(function(req, res, next) {
  if(1 !== mongoose.connection.readyState) {
    console.log('Database not connected');
    // Try a restart else it will stay down even when db comes back up
    mongoose.connect(app.set("db-uri"));
    res.render("system/maintenance", {
      status: 500
    });
  } else {
    return next();
  }
});

app.use(express.session({
  secret: settings.sessionSecret,
  maxAge: new Date(Date.now() + 3600000),
  store: store
}));

似乎工作 - 我担心会话商店不会恢复,但我认为它有效。