如何在 app.listen() 之前或之后在 koa 中执行一些数据库命令

How to execute some database commands in koa before or after app.listen()

期望的结果

我想在我的节点 + koa + mysql 服务器启动时或前后检查数据库的状态,并在需要时应用更新脚本。

server.js

中的最佳流量
  1. 设置MySQL连接
  2. 检查并更新数据库
    • 如果更新脚本出现问题或更新过程中出现意外错误,将崩溃并烧毁。
  3. 添加路线
  4. 启动服务器

我认为数据库的更新可以在#1 之后的任何时候完成,但我还不太成功。

我的工作主要基于 https://github.com/chrisveness/koa-sample-web-app-api-mysql 中的示例代码,尽管它更简单,只关注 api。

代码片段

// schema/fate2.js
const versionModel = require('../models/version');
module.exports = function* updateToHead() {
  yield versionModel.init();
  try {
    yield syncTrunkAndDev();
  } catch (e) {
    console.log("Latest trunk schema version is: " + versionModel.getTrunkLast());
    console.log("Latest dev schema version is: " + versionModel.getDevLast());
    throw "Error in upgrading", e;
  }
}

// server.js
app.use(require('./schema/fate2'));
...
app.listen(process.env.PORT||3030);

// models/version.js
const Version = module.exports = {};

Version.init = function*() {
  yield GLOBAL.db.query(
  "CREATE TABLE IF NOT EXISTS version ( " +
    " id int(11) NOT NULL," +
    " dev int(1) NOT NULL," +
    " description varchar(50) NOT NULL," +
    " applied_on timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP," +
    " dirty int(1) NOT NULL DEFAULT '1'," +
    " PRIMARY KEY (id)" +
  ") ENGINE=InnoDB DEFAULT CHARSET=utf8"
  );
};

其他 Whosebug 帖子

- 我读了这篇文章并试过了,但它似乎没有做任何事情。

最简单的解决方案可能是将 app.listen 包装在 co 进程中,这样您就可以在启动服务器之前按顺序生成启动过程。

如果它们中的任何一个抛出,那么执行将跳过 app.listen,您可以轻松地在一个地方捕获所有异常:

const co = require('co');

co(function*() {
  yield require('./schema/fate2');
  yield require('./models/version').init();
  app.listen(3000, function() { console.log('listening on 3000') });
}).catch(function(err) {
  console.error('Server boot failed:', err, err.stack);
});

我之前也在 Github 上偶然发现了 https://github.com/node-modules/ready-callback,但没有什么可说的了。

解决问题的过程是正确的,但经过大量挖掘,问题的根源是生成器函数的错误调用。