我在涉及事件处理程序的集成测试之一中使用 async 时遇到问题。 问题是在发出事件之前需要设置事件处理程序(引用异步提供的回调)。 但是,事件处理程序代码需要立即进行额外的回调。
这是一个显示问题的简化示例:
async.auto({
// This needs to run first, but it will finish second
event: [(next) => {
emitter.once('awesome', next);
}],
// This needs to finish near the end
checkResults: ['event', (results, next) => {
assert(results.event.status == 200);
assert(results.event.msg == 'cool');
// Do other async stuff...
somethingAsync(next);
}],
// This has to start second, but before the first one finishes
emit: ['event', (results, next) => {
event.emit('awesome', {msg: 'cool'}, next);
}],
checkEmit: ['emit', (results, next) => {
// some sort of check that can be async
},
], done);
event
必须首先开始,但在emit
发生之前不会结束。 emit
需要等待event
开始,而不是结束(也就是设置处理程序)。 因此这不会完成。
有没有办法用当前的异步库来做到这一点? (以干净的方式)
这是我想要的解决方案,假设这可以在异步中实现
async.auto({
listen: [(next, done) => {
client.on(done);
return next();
},
...
}, callback);
我可以使用并行,将发声器和侦听器(在测试中可以有多个)作为任务数组运行。 获取结果,并将检查作为第二部分。 但是,按顺序启动任务不需要技术上的并行(尽管可能会)。 此外,代码变得不那么平坦,尤其是在更复杂的设置中。
嗨@Saevon ,感谢您的提问!
一种快速、干净的方法是:
async.auto({
// This needs to finish near the end
checkResults: [(next) => {
return next(null, (results, next) => {
assert(results.event.status == 200);
assert(results.event.msg == 'cool');
// Do other async stuff...
// somethingAsync(next);
});
}],
// This needs to run first, but it will finish second
event: ['checkResults', (handler, next) => {
emitter.once('awesome', handler.checkResults);
return next();
}],
// This has to start second, but before the first one finishes
emit: ['event', (results, next) => {
// Should this be emitter.emit instead of event.emit?
event.emit('awesome', {msg: 'cool'}, next);
}],
checkEmit: ['emit', (results, next) => {
// the results of `checkResults` will be in `results.emit`
// as the handler on 'awesome' was passed the `next`
// callback from `emit`
// some sort of check that can be async
yourChecks(next);
}]
}, function done(err) {
// everything finished running, unless `err` !== `null`
});
本质上,您只是交换了event
和checkResults
依赖项,这实际上可能更简洁一些,因为event
取决于checkResults
的处理程序。 checkResults
现在只是将处理程序传递给event
。
执行顺序为:
checkResults --> event --> emit --> handler (passed to event from checkResults) --> checkEmit --> done
。
让我知道是否有任何不清楚的地方。
是的,这解决了问题。 谢谢!
我认为这是我见过的最疯狂的汽车用例:building_construction:
同意。 通常异步回调和事件发射器不能很好地混合...
最有用的评论
我认为这是我见过的最疯狂的汽车用例:building_construction: