我正在使用框架expressjs进行测试,我在其中创建一个在路由块之前运行的中间件,但它无法正常工作。
我认为可能是我的代码逃脱了异步并且它无法正常运行,但我对代码进行了一些更改,故障仍然让我失望。对于我做的更多测试和尝试,我找不到错误。
我的代码如下:
function getData(hostname, number, string, cb) {
async.waterfall([
function(callback) {
console.log('1');
callback(null, null);
},
function(first, callback) {
console.log('2');
callback(null, null);
},
function(second, callback) {
console.log('3');
callback(null, []);
}
],
function(err, results) {
if( typeof cb === 'function') {
return cb(null, results);
}
return results;
});
}
// Request middleware
app.use(function(req, res, next) {
res.locals['data'] = getData(req.hostname, 40, 'demo');
next();
});
app.get('/demo', function(req, res) {
res.send('Demo');
console.log( JSON.stringify( res.locals ) );
});
控制台上的输出如下(在该中间件返回值之前运行):
debug: 1 {} GET /demo 200 10.654 ms - 9 debug: 2 debug: 3 GET /favicon.ico - - ms - -
只有在以下列方式修改代码时才能正确使用我:
// Request middleware
app.use(function(req, res, next) {
if( req.method === 'GET' ) { // Only get request
getData(req.hostname, 40, 'demo', function(err, data) {
req.locals['data'] = data;
next();
});
} else {
next();
}
});
但我认为这是扩展代码,重复调用和检查。我知道,因为它不能与返回值的上述代码一起使用。我认为使用异步瀑布运行代码系列并且直到最后都不返回,阻止代码。
不应该同步并阻止代码的继续吗?
谢谢。
答案 0 :(得分:2)
正如您所指出的,问题是getData立即返回。 async
没有“逃避异步”,它是一组以异步方式围绕控制流的模式。结果仍然是异步的。另外,请勿使用“deasync”库。
您可能对使用生成器的koa
感兴趣(需要ES6 - 即节点v4或带有--harmony的节点0.12),以便让您编写较少“回调”驱动的代码。例如这将是koa中间件:
app.use(function*(next) {
res.locals['data'] = yield getData(req.hostname, 40, 'demo');
yield* next;
});
答案 1 :(得分:-1)
这里有一个基本的控制流问题。您的getData函数同时尝试同步和异步,同时使用纯异步控制流。
async.waterfall
方法用于一个接一个地执行一系列异步方法,将结果从一个方法传递到链中的下一个方法。如果任何方法回调错误,瀑布将被中断。
根据这些信息,您应该重构getData()
方法:
function getData(hostname, number, string, cb) {
async.waterfall([
function(callback) {
console.log('1');
callback();
},
function(first, callback) {
console.log('2');
callback();
},
function(second, callback) {
console.log('3');
callback(null, []);
}
],
function(err, results) {
return cb(err, results);
});
}
现在,在将此方法连接到中间件时,您可以将next
函数作为回调值传递:
app.use(function(req, res, next) {
getData(req.hostname, 40, 'demo', function(err, results) {
res.locals.data = results;
next(err);
});
});
我希望这是有道理的。基本上你只是在这里混合和匹配同步和异步概念。