在 Koa v2 中仅在服务器启动时一次性执行中间件
Execute a middleware one-time only at server startup in Koa v2
我创建了这个中间件,它只在网站中的任何路由第一次被访问者点击时执行一次:
// pg-promise
const db = require('./db/pgp').db;
const pgp = require('./db/pgp').pgp;
app.use(async (ctx, next) => {
try {
ctx.db = db;
ctx.pgp = pgp;
} catch (err) {
debugErr(`PGP ERROR: ${err.message}` || err);
}
await next();
});
// One-Time middleware
// https://github.com/expressjs/express/issues/2457
const oneTime = (fn) => {
try {
let done = false;
const res = (ctx, next) => {
if (done === false) {
fn(ctx, next);
done = true;
}
next();
};
return res;
} catch (err) {
debugErr(`oneTime ERROR: ${err.message}` || err);
}
};
const oneTimeQuery = async (ctx) => {
const result = await ctx.db.proc('version', [], a => a.version);
debugLog(result);
};
app.use(oneTime(oneTimeQuery));
此代码仅在用户访问网站时首次执行,结果:
app:log Listening on port 3000 +13ms
app:req GET / 200 - 24ms +2s
23:07:15 connect(postgres@postgres)
23:07:15 SELECT * FROM version()
23:07:15 disconnect(postgres@postgres)
app:log PostgreSQL 9.6.2, compiled by Visual C++ build 1800, 64-bit +125ms
我的问题是我想在服务器启动时执行它,当网站上没有任何访问时。
此代码的未来目的将是检查数据库中是否存在表。
解法:
在 const server = http.createServer(app.callback());
声明之前将其放在 ./bin/www
中有帮助:
const query = async () => {
const db = require('../db/pgp').db;
const pgp = require('../db/pgp').pgp;
const result = await db.proc('version', [], a => a.version);
debugLog(`www: ${result}`);
pgp.end(); // for immediate app exit, closing the connection pool (synchronous)
};
query();
您可以使用需要您的应用程序的 js 脚本启动您的应用程序,并使用节点的本机 http 模块来启动服务器。与 koa-generator 完全一样 (click).
这在您的 app.js 文件中:
const app = require('koa')();
...
module.exports = app;
然后这是启动服务器的脚本:
const app = require('./app');
const http = require('http');
[this is the place where you should run your code before server starts]
const server = http.createServer(app.callback());
server.listen(port);
之后您开始申请:
node [script_name].js
当然,这样做时请记住节点的异步性质。我的意思是 - 运行 callback/promise 中 'server' 变量的 'listen' 方法。
我创建了这个中间件,它只在网站中的任何路由第一次被访问者点击时执行一次:
// pg-promise
const db = require('./db/pgp').db;
const pgp = require('./db/pgp').pgp;
app.use(async (ctx, next) => {
try {
ctx.db = db;
ctx.pgp = pgp;
} catch (err) {
debugErr(`PGP ERROR: ${err.message}` || err);
}
await next();
});
// One-Time middleware
// https://github.com/expressjs/express/issues/2457
const oneTime = (fn) => {
try {
let done = false;
const res = (ctx, next) => {
if (done === false) {
fn(ctx, next);
done = true;
}
next();
};
return res;
} catch (err) {
debugErr(`oneTime ERROR: ${err.message}` || err);
}
};
const oneTimeQuery = async (ctx) => {
const result = await ctx.db.proc('version', [], a => a.version);
debugLog(result);
};
app.use(oneTime(oneTimeQuery));
此代码仅在用户访问网站时首次执行,结果:
app:log Listening on port 3000 +13ms
app:req GET / 200 - 24ms +2s
23:07:15 connect(postgres@postgres)
23:07:15 SELECT * FROM version()
23:07:15 disconnect(postgres@postgres)
app:log PostgreSQL 9.6.2, compiled by Visual C++ build 1800, 64-bit +125ms
我的问题是我想在服务器启动时执行它,当网站上没有任何访问时。
此代码的未来目的将是检查数据库中是否存在表。
解法:
在 const server = http.createServer(app.callback());
声明之前将其放在 ./bin/www
中有帮助:
const query = async () => {
const db = require('../db/pgp').db;
const pgp = require('../db/pgp').pgp;
const result = await db.proc('version', [], a => a.version);
debugLog(`www: ${result}`);
pgp.end(); // for immediate app exit, closing the connection pool (synchronous)
};
query();
您可以使用需要您的应用程序的 js 脚本启动您的应用程序,并使用节点的本机 http 模块来启动服务器。与 koa-generator 完全一样 (click).
这在您的 app.js 文件中:
const app = require('koa')();
...
module.exports = app;
然后这是启动服务器的脚本:
const app = require('./app');
const http = require('http');
[this is the place where you should run your code before server starts]
const server = http.createServer(app.callback());
server.listen(port);
之后您开始申请:
node [script_name].js
当然,这样做时请记住节点的异步性质。我的意思是 - 运行 callback/promise 中 'server' 变量的 'listen' 方法。