Подтвердить что ты не робот

Как фильтровать RXJS ArrayObservable

У меня есть массив, который я хотел бы фильтровать. Звучит просто, я знаю. Но когда я это делаю, я все равно получаю весь массив...

constructor(http:Http) {
    this._val = Math.random();
    let s = http.get('https://secure.digitalsignage.com/Digg');
    s.map(s => {
        let news = JSON.parse(s._body);
        return Rx.Observable.fromArray(news);
    }).filter(function(data) {
        console.log('all array ' + data);
        return true;
    }).subscribe(function (v) {
        console.log(v);
    });
}

поэтому в console.log('all array' + data); Я получаю весь массив вместо потока отдельных элементов массива, почему?

здесь отладка:

введите описание изображения здесь

Я знаю, что я не сумасшедший, потому что это работает так, как ожидалось:

 Rx.Observable.fromArray([1, 2, 3, 4, 5]).filter(function (v) {
        if (v < 3)
            return true
        return false;
    }).subscribe(function (v) {
        console.log(v);
    })

что дает?

tx для чтения,

Шон.

4b9b3361

Ответ 1

Вам нужно использовать concatMap/flatMap или любой другой оператор, который выравнивает последовательность наблюдаемых.

На данный момент .filter получает наблюдаемые, а не отдельные элементы массива (все, что вы делаете, превращает массив в наблюдаемый массив). Второй пример работает так, как вы применяете фильтр к тому, который наблюдается непосредственно),

Попробуйте следующее:

constructor(http:Http) {
  this._val = Math.random();
  let s = http.get('https://secure.digitalsignage.com/Digg');
  s.flatMap(s => {
    let news = JSON.parse(s._body);
    return Rx.Observable.fromArray(news);
  }).filter(function(data) {
    console.log('all array ' + data);
    return true;
  }).subscribe(function (v) {
    console.log(v);
  });
}

Вам нужно сделать это, как в противном случае (используя #map) иметь наблюдаемые наблюдаемые (вы возвращаете наблюдаемое внутри наблюдаемого), но хотите работать с фактическими значениями, содержащимися в новостях (а не на наблюдаемом, содержащем их). Это несколько напоминает разницу между конкатенированием массива и просто добавлением его в качестве элемента.

Другим допустимым способом сделать это будет использование карты, как вы делали раньше, но слияние испускаемых наблюдаемых (flatMap/concatMap просто карта и слияние за один раз)

constructor(http:Http) {
  this._val = Math.random();
  let s = http.get('https://secure.digitalsignage.com/Digg');
  s.map(s => {
    let news = JSON.parse(s._body);
    return Rx.Observable.fromArray(news);
  }).mergeAll() // here you flatten the observable - i.e. you emit just the values contained in incoming observables and lose the observables themselves
    .filter(function(data) {
    console.log('all array ' + data);
    return true;
  }).subscribe(function (v) {
    console.log(v);
  });
}

Если вы этого не поняли, не волнуйтесь, люди, которые могут объяснить это лучше меня:)