为什么过滤可观察订阅的结果会产生与过滤observable本身不同的结果

时间:2016-06-17 08:43:39

标签: javascript filter rxjs observable

我正在使用此代码:

var rx = require('rxjs');
var fetch = require('isomorphic-fetch');

var urls = [
  'http://gundam.wikia.com/api/v1/Navigation/Data'
];

var gundams = rx.Observable
  .from(urls)
  .flatMap(x => fetch(x))
  .flatMap(x => x.json())
  .map(x => x.navigation.wiki)
  .filter(x => x.text === "Mobile Weapons");

gundams.subscribe(
  (n) => console.log(n),
  (e) => console.log(e),
  (d) => console.log('done')
);

我目前没有记录到控制台的结果('已完成')。

如果我删除了我的可观察对象(.filter(x => x.text === "Mobile Weapons");)上的最后一个链并更改了

(n) => console.log(n),

(n) => console.log(n.filter(x => x.text === "Mobile Weapons")),

我将预期结果记录到控制台

[ { text: 'Mobile Weapons', href: '/wiki/Special:RunQuery/Weapon_query', children: [ [Object], [Object], [Object], [Object] ] } ]

我可能只是误解了observable的工作方式,但我很好奇我如何更改代码而不必在subscribe回调中使用过滤器。

1 个答案:

答案 0 :(得分:1)

这是因为map正在返回对象数组,因此您的过滤器函数会接收数组,而不是您尝试过滤的数组内容。

这与在订阅中执行此过滤器时的工作原理相同。由于map返回了对象数组,因此您可以过滤该数组并按预期工作。

您需要使用flatMap,以便过滤器接收数组中的项而不是数组。

var urls = [
  'http://output.jsbin.com/qimutofedi.json'
];

var gundams = Rx.Observable
  .from(urls)
  .flatMap(x => fetch(x))
  .flatMap(x => x.json())
  .flatMap(x => x.navigation.wiki) // <--- flatten out the array to emit its values
  .filter(x => x.text === "Mobile Weapons");

gundams.subscribe(
  (n) => console.log(n),
  (e) => console.log(e),
  (d) => console.log('done')
);

以上将记录:

Object {text: "Mobile Weapons", href: "/wiki/Special:RunQuery/Weapon_query",children: Array[4]}
children:Array[4]
href:"/wiki/Special:RunQuery/Weapon_query"
text:"Mobile Weapons"
__proto__:Object

jsbin example