rx js: Как я могу сделать "из" наблюдаемых значений выбросов после подписки? - PullRequest
0 голосов
/ 16 апреля 2020

Я создал обычный строковый массив и выделил из него наблюдаемое, используя «from»

import {  from } from 'rxjs';

const strArr = ['aaa', "bbb", "ccc"];

const fsa = from(strArr);

Если перед подпиской я получу sh значение исходного массива, я получу это значение в потоке данных.

strArr.push("coke")

fsa.subscribe(
  x=>console.log(x) // outputs -> aaaa bbbb cccc coke
)

Однако, если я добавлю sh другой элемент в исходный массив до подписки, ничего не произойдет (он не будет реагировать)

strArr.push("coke")

fsa.subscribe(
  x=>console.log(x) // outputs -> aaaa bbbb cccc coke
) 

strArr.push("pepsi") // Still outputs -> aaaa bbbb cccc coke.

Я ожидал, что fsa Observable отреагирует на каждый элемент, добавленный в исходный массив, поскольку он создается «из» этого.

Почему вызывает такое поведение?

Спасибо.

Ответы [ 3 ]

2 голосов
/ 16 апреля 2020

Другой альтернативой является объединение BehaviorSubject с javascript Proxy для отслеживания каждого типа изменений в массиве

import {BehaviorSubject,Subject} from 'rxjs'
var originalArray = [];
const arrayChange=new BehaviorSubject(originalArray)
arrayChange.subscribe(console.log)

var arrayChangeHandler = {
  set: function(target, property, value, receiver) {
    console.log('setting ' + property + ' for ' + target + ' with value ' + value);
    target[property] = value;
    // you can emit more context to the stream if you wish
    arrayChange.next(target)
    // you have to return true to accept the changes
    return true;
  }
};

var arrayProxy = new Proxy( originalArray, arrayChangeHandler );
arrayProxy.push(1)
arrayProxy.push(2)
arrayProxy.pop()
1 голос
/ 16 апреля 2020

с массивом это не так просто, но вместо массива вы можете использовать тему.

Вопрос: нужен ли вам массив или лучше использовать тему вместо нее?

const stream$ = new ReplaySubject();
stream$.next('aaa');
stream$.next('bbb');
stream$.next('ccc');

stream$.subscribe(console.log); // [aaa bbb ccc]

stream$.next('ddd');
stream$.subscribe(console.log); // [aaa bbb ccc ddd], and the first subscription gets just 'ddd'.

Если вы хотите прослушивать изменения в массиве, лучше всего написать собственный Observable, который переопределяет метод pu sh и выдает его в поток. Дайте мне знать, если это так, и я могу обновить пример кода.

0 голосов
/ 16 апреля 2020

Я нашел решение для того, что я пытаюсь сделать. (Пусть подписчик отреагирует на дальнейшие изменения в массиве после подписки, надеюсь, он поможет тем, у кого похожие вопросы:

import { ReplaySubject } from 'rxjs';

const rSubject$ = new ReplaySubject();

const rSubjAsObs = rSubject$.asObservable();

// string
const str =  "I am afraid I can not do that, Dave";
//string no spaces
let strNoSpace = str.replace(/\s+/g, ''); 
//word array
let srtArr = str.split(' ');

srtArr.forEach(word=>rSubject$.next(word))

rSubjAsObs.subscribe(
  data=>console.log(data)
)

rSubject$.next("...said the good machine");
...