rxjs:扫描累加器突变

时间:2018-11-29 19:55:27

标签: rxjs rxjs6

我(错误地)觉得扫描操作员每次通过总是返回一个新对象。我最近发现情况并非如此。

我已经将learnrxjs.io的示例进行了分叉,以说明我的意思here

看一下代码:

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 :(得分:3)

是的,您要更改的是对象引用-> acc。您可以如下冻结对象,以阻止其变异。

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