因此,我们正在尝试将express
服务器重写为Rx
。它目前正在使用async
进行所有流操作。代码如下所示:
var async = require('async');
function getCountAndChannels(name, cb){
var tasks = [
function(cb) {
//does a mongoDB search and returns count
},
function(cb) {
//does a findOne mongoDB search and returns
}
];
async.parallel(tasks, cb);
}
router.get('data', function(req, res) { //router is the express router
var recorders = req.query.recorders.split(',');
async.map(recorders, function(name, cb) {
getCountAndChannels(name, cb);
}, function(err, countsAndChannels) {
if(err) throw err;
// here countsAndChannels is an array with first element the count
// and second element the document.
// do other async stuff based on the results
res.status(200).json('send some calculations');
});
我要做的就是循环遍历recorders
数组,并为每一个计算两个mongoDB搜索。我尝试使用Rx.Observable.merge
,它不会在数组中返回结果,而是在2个不同的回调调用中。那么,我尝试了Rx.Observable.zip
,我相信这就是我正在寻找的。 p>
问题是我不知道如何遍历recorders
并在所有操作完成后发送结果。因为简单的forEach
循环会引发Cannot set headers after they are sent
错误。
这是我到目前为止所做的:
recorders.forEach(recorder => {
Rx.Observable.zip([
search1,
search2
]).subscribe(
(countsAndChannels) => {
// do stuff
res.send('the results');
},
err => res.status(500).json(err),
() => res.send('OK')
);
});
之前没有使用过Rx,所以感谢任何帮助。
答案 0 :(得分:0)
将记录器列表转换为Observable流可能更容易,然后flatMap
转换每个记录器(即执行异步处理),然后调用toArray
将所有结果存储到数组中:
var recorder$ = Rx.Observable.from(recorders);
var countsAndChannels$ = recorder$
.flatMap(performAsyncTask);
// allResults$ will emit once all of the async work is complete
var allResults$= countsAndChannels$.toArray();
allResults$.subscribe(results => {
// Send response to client;
});