我有多个父对象,每个对象都有多个子对象,每个子对象都有多个链接。我想查看所有子项链接,删除没有实时链接的子项,并删除已删除所有子项的父项。
我正在尝试了解如何使用角度4中的Rx编写以下代码:
parents.reduce((updatedParents, parent) => {
parent.children = parent.children.reduce((updatedChildern, child) => {
child.links = child.links.reduce((updatedLinks, link) => {
if (link is live) updatedLinks.push(link) // asnyc operation
return updatedLinks;
},[]);
if (child.links.length) updatedChildren.push(child);
},[]);
if (parent.children.length) updatedParents.push(parent);
},[])
我可以想象如何使用promises做到这一点,并使用bluebird承诺all / promise.reduce等,但是我如何使用Observable实现这个并减少等?我真的很困惑,我不知道该怎么做。我尝试了几种方法,无法让它发挥作用。我希望单个事件能够将过滤后的结果返回给我,就像承诺一样。
欢迎任何建议。
这是结构:
const parents = [
{
children: [
{
links: [
'http://www.onelink.com', 'http://www.secondlink'
]
},
{
links: [
'http://www.threelink.com', 'http://www.fourlink'
]
}
]
},
{
children: [
{
links: [
'http://www.fivelink.com', 'http://www.sixlink'
]
},
{
links: [
'http://www.sevenlink.com', 'http://www.egihtlink'
]
}
]
}
这是我走了多远。
return Observable.from(parents)
.flatMap(parent => Observable.from(parent.children)
.flatMap(child => Observable.from(child.images)
.reduce((updatedImages, imgSrc, idx) => {
return this.http.get(imgSrc)
.map(res => {
if (res.status === 200) {
updatesImages.push(base64Ecode(imgSrc));
}
console.log(res);
console.log(updatedImages);
return updatedImages;
});
})
.filter(p => p.length !== 0)
)
.filter(c => c.length !== 0)
答案 0 :(得分:0)
你可以尝试使用filter而不是reduce,因为reduce更多是用于压缩数据而不是基于过滤器删除。
可能有更好的方法从角度ping而不是仅仅抓住整个页面,但想法是一样的。
const parents = [
[
[
"http://www.onelink.com",
"http://www.secondlink"
],
[
"http://www.threelink.com",
"http://www.fourlink"
]
],
[
[
"http://www.fivelink.com', 'http://www.sixlink"
],
[
"http://www.sevenlink.com",
"http://www.egihtlink"
]
]
];
function getLiveLinks() {
parents.filter((child) => {
return child.filter((link) => {
console.log(link)
http.get(link).toPromise().then((res)=>{
live = res;
//check if resolved and return if true
});
}).length > 0;
});
}
答案 1 :(得分:0)
这很棘手,因为起始结构是不可观察的。 在我看来,最好首先解决所有链接,然后使用不可观察缩减的变体。
// simulated http.get
const http = { get: link => Rx.Observable.of([link, link.endsWith('.com')])}
// non-observable flatMap
const flatMap = (a, cb) => [].concat(...a.map(cb))
const links = flatMap(parents, x => flatMap(x.children, y => y.links))
console.log(links)
// Rx version of Promise.all()
const linkTests$ = Rx.Observable.forkJoin(links.map(link => http.get(link)))
linkTests$.subscribe(linkTests => {
const isLive = link => linkTests.some(linkTest => linkTest[0] === link && !!linkTest[1])
const liveLinks = links => links.filter(link => isLive(link))
const liveChildren = children => children.filter(child => {
child.links = liveLinks(child.links)
return child.links.length
})
const liveParents = parents => parents.filter(parent => {
parent.children = liveChildren(parent.children)
return parent.children.length
})
console.log(liveParents(parents))
})
工作示例:CodePen