我正在编写一个中间件,它将执行一系列操作。序列完成后,我希望中间件调用next()。从这一点来看,中间件是多余的。 我编写了以下代码:(这里的动作序列是通过调用setTimeout来模拟的):
function myMiddleware(req, res, next){
console.info("inside myMiddleware");
if (actionDone) {
console.info("middleware redundant. ActionDone, calling next");
next();
}
setTimeout(doneWaiting, 30000);
function doneWaiting(){
actionDone = true;
next();
}
}
此代码无效,因为如果在操作完成之前有多个请求到达,则会一次又一次地调用setTimeout。我希望setTimeout只被调用一次,并且只有当它完成时我才想对到目前为止到达的所有请求调用next()。
实现这一目标的最佳方法是什么?
谢谢, 李
答案 0 :(得分:1)
如果我理解正确,您希望执行任务并在任务完成后处理所有请求?在那之前他们会等待吗?
所以这是不可扩展的方式:
var EventManager = new require("events").EventEmitter( );
var actionDone = "start";
function myMiddleware(req, res, next){
console.info("inside myMiddleware");
var handler = function( ) {
console.info("middleware redundant. ActionDone, calling next");
next();
};
if (actionDone === "finished" ) {
handler( );
return;
}
EventManager.once( "finished", handler );
if (actionDone !== "working") {
actionDone = "working";
function doneWaiting(){
actionDone = "finished";
EventManager.trigger( "finished" );
}
setTimeout(doneWaiting, 30000);
}
}
显然它不可扩展,因为你无法在机器之间共享EventManager
对象。为了在机器之间执行此操作,您可能必须从主服务器向每个其他服务器发出请求并以类似方式处理请求。
警告:您尝试做的事情看起来非常糟糕。毕竟请求不应该相互依赖。这很容易导致服务器崩溃。
答案 1 :(得分:0)
将actionDone
变量设为req
,这样
function myMiddleware(req, res, next){
console.info("inside myMiddleware");
if (req.actionDone) {
console.info("middleware redundant. ActionDone, calling next");
next();
}
setTimeout(doneWaiting, 30000);
function doneWaiting(){
req.actionDone = true;
next();
}
}