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()

示例:https://jsfiddle.net/3u43176d/

我想出了一些通用的方法,以防你有未知数量的动物:

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