[英]convert async to Rx.js
So, we are trying to rewrite our express
server into Rx
. 因此,我们正在尝试将
express
服务器重写为Rx
。 It is currently using async
for all stream operations. 当前,它对所有流操作都使用
async
。 The code looks like the following: 该代码如下所示:
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');
});
The thing here I have to do is loop over the array of recorders
and for each one calculate the two mongoDB searches. 我要做的事情是遍历一系列
recorders
并为每个recorders
计算两个mongoDB搜索。 I have tried using Rx.Observable.merge
which doesn't return the results in an array but in 2 different calls of the callback. 我尝试使用
Rx.Observable.merge
,它不会在数组中返回结果,而是在回调的2个不同调用中返回结果。 So, then I tried Rx.Observable.zip
which I believe is what I'm looking for. 所以,然后我尝试了
Rx.Observable.zip
,我相信这是我想要的。
The problem is I don't know how to loop over the recorders
and send the result when all operations are finished. 问题是我不知道如何在所有操作完成后遍历
recorders
并发送结果。 Because a simple forEach
loop will throw a Cannot set headers after they are sent
error. 因为一个简单的
forEach
循环将Cannot set headers after they are sent
错误Cannot set headers after they are sent
引发Cannot set headers after they are sent
。
This is what I have so far: 这是我到目前为止的内容:
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')
);
});
Haven't used Rx before, so any help is appreciated. 以前没有使用过Rx,因此不胜感激。
It might be easier to convert your list of recorders to an Observable stream, then flatMap
over each recorder (ie perform your async processing), then call toArray
to store all the results into an array: 将记录器列表转换为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.