[英]convert async to Rx.js
因此,我们正在尝试将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
并为每个recorders
计算两个mongoDB搜索。 我尝试使用Rx.Observable.merge
,它不会在数组中返回结果,而是在回调的2个不同调用中返回结果。 所以,然后我尝试了Rx.Observable.zip
,我相信这是我想要的。
问题是我不知道如何在所有操作完成后遍历recorders
并发送结果。 因为一个简单的forEach
循环将Cannot set headers after they are sent
错误Cannot set headers after they are sent
引发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,因此不胜感激。
将记录器列表转换为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;
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.