Javascript rxjs内部本机映射正在提前退出

Javascript rxjs内部本机映射正在提前退出,javascript,rxjs,observable,rxjs5,Javascript,Rxjs,Observable,Rxjs5,假设有一个端点返回结构中的内容: { results: [ {hoofed: { //animal1 } }, {feline: { //animal2 }}, {other: { //animal3 }} ] } 假设我有这样的事情: import {RxHR} from '@akanass/rx-http-request' return RxHR.get('www.third_part

假设有一个端点返回结构中的内容:

{
  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]

相反,这只返回与其中一个条件匹配的第一项,例如
[animal1]
,而不是像我所期望的那样将数组映射到另一个数组。我的问题是,为什么?我怎样才能实现这样的内部转换呢?

实际上,您的流将返回类似
[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()

示例:

实际上,您的流将返回类似
[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"
  }
]
如果您想尝试一下,这里有一个可行的建议:

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

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"
  }
]
如果您想尝试一下,这里有一个可行的建议:

结果是什么?你能添加一个对象来描述它吗?更深入地描述我所期望的结果吗?你能添加一个对象来描述它吗?描述得比我想象的更深入