我正在尝试从Stash Rest Api拉取请求中构造一个可观察的值流。不幸的是,PR的合并冲突是否有合并冲突的信息可以在合并列表的不同端点获得。
打开拉取请求列表可以在http://my.stash.com/rest/api/1.0/projects/myproject/repos/myrepo/pull-requests
中看到对于每个PR,合并冲突的数据在http://my.stash.com/rest/api/1.0/projects/myproject/repos/myrepo/pull-requests/[PR-ID]/merge
处可见使用atlas-stash包,我可以创建和订阅一个可观察的拉取请求流(每秒更新):
let pullRequestsObs = Rx.Observable.create(function(o) {
stash.pullRequests(project, repo)
.on('error', function(error) {o.onError(error)})
.on('allPages', function(data) {
o.onNext(data);
o.onCompleted();
});
});
let pullRequestStream = pullRequestsObs
.take(1)
.merge(
Rx.Observable
.interval(1000)
.flatMapLatest(pullRequestsObs)
);
pullRequestsStream.subscribe(
(data) => {
console.log(data)
// do something with data
},
(error) => log.error(error),
() => log.info('done')
);
这可以按照我的意愿和期望进行。最后,pullRequestsStream
是一个可观察的,其值是JSON对象的列表。
我希望更新pullRequestsStream
值,以便列表中的每个元素都包含来自[PR-ID]/merge
api的信息。
我认为可以使用map
pullRequestsStream
来实现这一点,但我没有成功。
let pullRequestWithMergeStream = pullRequestStream.map(function(prlist) {
_.map(prlist, function(pr) {
let mergeObs = Rx.Observable.create(function(o) {
stash.pullRequestMerge(project, repo, pr['id'])
.on('error', function(error) {o.onError(error)})
.on('newPage', function(data) {
o.onNext(data);
o.onCompleted();
}).take(1);
});
mergeObs.subscribe(
(data) => {
pr['merge'] = data;
return pr; // this definitely isn't right
},
(error) => log.error(error),
() => log.info('done')
);
});
});
通过一些日志记录,我可以看到pull-request和merge apis都被正确命中,但是当我订阅pullRequestWithMergeStream
时我
得到未定义的值。
在return
内的subscribe
步骤中使用map
不起作用(似乎不应该这样)但我无法弄清楚什么样的模式/成语会实现我想要的。
有没有正确的方法呢?我完全走错了轨道吗?
我可以使用来自不同的可观察的信息更新Rxjs.Observable中的值吗?
答案 0 :(得分:2)
您可以使用flatMap
或concatMap
让一个任务触发另一个任务。您可以使用forkJoin
并行请求合并,并将结果收集到一个位置。它没有经过测试,但它应该是这样的:
pullRequestStream.concatMap(function (prlist){
var arrayRequestMerge = prlist.map(function(pr){
return Rx.Observable.create(function(o) {...same as your code});
});
return Rx.Observable.forkJoin(arrayRequestMerge)
.do(function(arrayData){
prlist.map(function(pr, index){pr['merge']=arrayData[index]
})})
.map(function(){return prlist})
})
PS:我认为prlist
是一个数组。
<强>更新强>
在您发表评论之后,这是一个只能在并行运行maxConcurrent
次调用的版本。
pullRequestStream.concatMap(function (prlist){
var arrayRequestMerge = prlist.map(function(pr, index){
return Rx.Observable.create(function(o) {
stash.pullRequestMerge(project, repo, pr['id'])
.on('error', function(error) {o.onError(error)})
.on('newPage', function(data) {
o.onNext({data: data, index : index});
o.onCompleted();
}).take(1);
});
});
var maxConcurrent = 2;
Rx.Observable.from(arrayRequestMerge)
.merge(maxConcurrent)
.do(function(obj){
prlist[obj.index]['merge'] = obj.data
})})
.map(function(){return prlist})
})