所以。在尝试为我正在构建的 Restify.js 应用程序实现一些基本中间件时,我遇到了一些怪癖,特别是关于
next()
和承诺回调。
以通用形式表达问题:
var server = restify.createServer({
name: config.name
});
承诺解决:
server.use(function checkAcl(req, res, next) {
// Promise is resolved
var promise = function () {
var deferred = require('q').defer();
deferred.resolve();
return deferred.promise;
}
promise()
.then(function () {
next(); // doesn't get 'called', no response sent, connection eventually times out
}, function () {
res.send(new restify.NotAuthorizedError());
});
});
server.use(restify.bodyParser());
...
承诺被拒绝
server.use(function checkAcl(req, res, next) {
// Promise is rejected
var promise = function () {
var deferred = require('q').defer();
deferred.reject();
return deferred.promise;
}
promise()
.then(function () {
next();
}, function () {
res.send(new restify.NotAuthorizedError()); // this works fine
});
}
});
server.use(restify.bodyParser());
...
我做错了什么吗?有什么见解吗?这似乎确实与承诺回调有关,它们是否以某种方式抑制了对
next()
的调用?
在自定义中间件之前添加
restify.bodyParser()
中间件可以解决问题。
n.b:
// Add bodyParser() to the stack before the custom middleware
server.use(restify.bodyParser());
server.use(function checkAcl(req, res, next) {
// Promise is resolved
var promise = function () {
var deferred = require('q').defer();
deferred.resolve();
return deferred.promise;
}
promise()
.then(function () {
next(); // next() now behaves as expected.
}, function () {
res.send(new restify.NotAuthorizedError());
});
});
...
除此之外,我最终偶然发现了这个 Github 问题,它描述了该问题以及另一种可能的解决方案(如果中间件的顺序很重要(可能确实如此))。
mcavage:很确定这实际上是节点在咬你(因为你的数据被发送到任何地方)。试试这个:
var server.createServer();
server.pre(restify.pre.pause());
...