rxjs 内部原生地图提前退出
rxjs inner native map is exiting early
所以假设有一个端点 returns 结构的东西:
{
results: [
{hoofed: {
//animal1
}
},
{feline: {
//animal2
}},
{other: {
//animal3
}}
]
}
假设我有这样的东西:
import {RxHR} from '@akanass/rx-http-request'
return RxHR.get('www.third_party.com')
.pluck('body')
.map(JSON.parse)
.pluck('results')
.map((animals) => animals.map((animal) => animal['hoofed'] || animal['feline']))
我希望它具有以下行为:
1) 提取响应正文。
2) 解析 JSON
3) 提取所有结果
4) 在有蹄或猫科动物键处拉取值,产生:
[animal1, animal2]
相反,这只是 returns 第一个符合其中一个条件的项目,例如[animal1]
而不是像我期望的那样将数组映射到另一个数组。我的问题是,为什么?我怎样才能实现这样的内在转变?
实际上,您的直播会 return 像 [animal1, animal2, undefined]
一样。流缺少过滤器运算符。
const flatAnimal = animal => animal['hoofed'] || animal['feline']
Rx.Observable.of(results)
.map(JSON.parse)
.map((animals) => animals.filter(flatAnimal).map(flatAnimal))
或者您可以将数组用作可观察序列
Rx.Observable.of(results)
.flatMap(JSON.parse)
.filter(flatAnimal)
.map(flatAnimal)
.toArray()
我想出了一些通用的方法,以防你有未知数量的动物:
const { Observable } = Rx;
// simulate exactly how we'll receive the HTTP response
const mockedData = JSON.stringify({
body: JSON.stringify({
results: [{
hoofed: {
name: 'animal1'
}
}, {
feline: {
name: 'animal2'
}
}, {
other: {
name: 'animal3'
}
}]
})
});
// mock the RxHR lib and return the equivalent of an HTTP request with observable.of and delay
const RxHR = {
get: (url) => Observable.of(mockedData).delay(1000)
};
// take an HTTP response and return the body
const resToJson = (res) => {
const fullRes = JSON.parse(res);
const body = JSON.parse(fullRes.body);
return body;
};
// for a given array of objects (1), having other objects(2) as value
// return an array of objects(2)
const flattenObjects = (objArr) => objArr.reduce((acc, curr) => {
const keys = Object.keys(curr);
keys.forEach(key => acc.push(curr[key]));
return acc;
}, []);
// nicely display the output : debug only
const niceOutput = (obj) => console.log(JSON.stringify(obj, null, 2));
const animals$ = RxHR
.get('www.third_party.com')
.map(resToJson)
.map(json => json.results)
.map(flattenObjects);
animals$
.do(niceOutput)
.subscribe();
输出:
[
{
"name": "animal1"
},
{
"name": "animal2"
},
{
"name": "animal3"
}
]
如果您想尝试一下,这里有一个可用的 Plunkr:
https://plnkr.co/edit/UkjfSrgHKoS3kqXwiYXA?p=preview
所以假设有一个端点 returns 结构的东西:
{
results: [
{hoofed: {
//animal1
}
},
{feline: {
//animal2
}},
{other: {
//animal3
}}
]
}
假设我有这样的东西:
import {RxHR} from '@akanass/rx-http-request'
return RxHR.get('www.third_party.com')
.pluck('body')
.map(JSON.parse)
.pluck('results')
.map((animals) => animals.map((animal) => animal['hoofed'] || animal['feline']))
我希望它具有以下行为:
1) 提取响应正文。
2) 解析 JSON
3) 提取所有结果
4) 在有蹄或猫科动物键处拉取值,产生:
[animal1, animal2]
相反,这只是 returns 第一个符合其中一个条件的项目,例如[animal1]
而不是像我期望的那样将数组映射到另一个数组。我的问题是,为什么?我怎样才能实现这样的内在转变?
实际上,您的直播会 return 像 [animal1, animal2, undefined]
一样。流缺少过滤器运算符。
const flatAnimal = animal => animal['hoofed'] || animal['feline']
Rx.Observable.of(results)
.map(JSON.parse)
.map((animals) => animals.filter(flatAnimal).map(flatAnimal))
或者您可以将数组用作可观察序列
Rx.Observable.of(results)
.flatMap(JSON.parse)
.filter(flatAnimal)
.map(flatAnimal)
.toArray()
我想出了一些通用的方法,以防你有未知数量的动物:
const { Observable } = Rx;
// simulate exactly how we'll receive the HTTP response
const mockedData = JSON.stringify({
body: JSON.stringify({
results: [{
hoofed: {
name: 'animal1'
}
}, {
feline: {
name: 'animal2'
}
}, {
other: {
name: 'animal3'
}
}]
})
});
// mock the RxHR lib and return the equivalent of an HTTP request with observable.of and delay
const RxHR = {
get: (url) => Observable.of(mockedData).delay(1000)
};
// take an HTTP response and return the body
const resToJson = (res) => {
const fullRes = JSON.parse(res);
const body = JSON.parse(fullRes.body);
return body;
};
// for a given array of objects (1), having other objects(2) as value
// return an array of objects(2)
const flattenObjects = (objArr) => objArr.reduce((acc, curr) => {
const keys = Object.keys(curr);
keys.forEach(key => acc.push(curr[key]));
return acc;
}, []);
// nicely display the output : debug only
const niceOutput = (obj) => console.log(JSON.stringify(obj, null, 2));
const animals$ = RxHR
.get('www.third_party.com')
.map(resToJson)
.map(json => json.results)
.map(flattenObjects);
animals$
.do(niceOutput)
.subscribe();
输出:
[
{
"name": "animal1"
},
{
"name": "animal2"
},
{
"name": "animal3"
}
]
如果您想尝试一下,这里有一个可用的 Plunkr:
https://plnkr.co/edit/UkjfSrgHKoS3kqXwiYXA?p=preview