rxjs: сканирование мутации аккумулятора - PullRequest
0 голосов
/ 29 ноября 2018

У меня (ошибочно) сложилось впечатление, что оператор сканирования всегда будет возвращать новый объект при каждом проходе.Недавно я обнаружил, что это не так.

Я разобрал пример из learnrxjs.io , чтобы продемонстрировать, что я имею в виду здесь .

Взглянув на код:

const subject = new Rx.Subject();

const example = subject.scan((acc, curr) => {
    console.log('Accumulator', acc);
    return Object.assign({}, acc, curr)
}, {});

//log accumulated values
const subscribe = example.subscribe(val => {
    val.mutating = 'test'
    console.log('Accumulated object:', val)
});

//next values into subject, adding properties to object
subject.next({name: 'Joe'}); 
// {name: 'Joe'}

subject.next({age: 30}); 
// {name: 'Joe', age: 30}

subject.next({favoriteLanguage: 'JavaScript'}); 
// {name: 'Joe', age: 30, favoriteLanguage: 'JavaScript'}

Я изменяю val, передаваемый по потоку в subscription, и выхожу из значения accumulator вscan функция аккумулятора.

Глядя на консоль, видно, что аккумулятор содержит mutating:"test" после первого и последующих проходов:

enter image description here

Если я не ошибаюсь, это демонстрирует, что я могу изменять потоковые объекты в любом месте по линии вверх и до подписки.Что, я полагаю, не удивляет меня, поскольку это ссылка на объект.Но я подумал, что оператор scan всегда будет возвращать новый объект, предотвращающий мутацию его внутреннего аккумулятора ...

Сначала я подумал о том, чтобы отобразить новый объект, подобный этому:

scan((acc, curr) => Object.assign({}, acc, curr), {}),
map(data=>Object.assign({}, data))

Но мне это кажется странным.

Является ли поведение, которое я демонстрирую, ожидаемым или я не понимаю, как все это работает?Как я могу предотвратить мутацию аккумулятора?

Спасибо

1 Ответ

0 голосов
/ 30 ноября 2018

Да, это ссылка на объект -> acc, которую вы меняете.Вы можете заморозить объект, как показано ниже, чтобы он не мутировал.

 return Object.freeze(Object.assign({},acc, curr));
...