如何为RxJS Observable的每个排放创建一个新对象?
我有一个服务,计算一个给定的Sudoku(实现不重要)的解决方案,并发布每个RxJS Observable计算迭代。如何为RxJS Observable的每个排放创建一个新对象?
solve() : Observable<Field[][]> {
let observable = Observable.create((o: Observer<Field[][]>)=> {
let iterationCount : number = 0;
while (!this.sudokuGame.isFinished() && iterationCount < 500) {
iterationCount++;
this.eliminateOptions();
o.next(this.sudokuGame.boardFields);
}
if(this.sudokuGame.isFinished())
o.complete();
else
o.error("The game could not be finished after 500 iterations.");
});
return observable;
}
我这样做,这样我可以在以后使用Observable.zip()
这个观察到的结合与Observable.interval()
观测显示这个解决过程经历与我的Angular2组分人类明显的延迟迭代。
但是,当我设置由可观察在我Angular2组分像这样发出的数据:
Observable.zip(this.sudokuSolverService.solve(),Observable.interval(500),(obs, timer) => {return obs}).subscribe((nextBoardFields: Field[][]) => {
this.sudokuGame.boardFields = nextBoardFields;
});
然后可观察到的排放被延迟,但更改显示瞬间不过。我怀疑这是由于我通过引用复制了nextBoardFields
引起的,但是我不知道任何方法可以将我的Angular2控制器中的boardFields
-Array与boardFields
- 中的数组取消关联,这是我的sudoku解决服务中的一个方法。
有没有可能做到这一点?
编辑:那我脑海是以某种方式使Field
类不可变的(也许Immutable.js的帮助下),这似乎对这个问题有点复杂的唯一的事情。
我已经使用Object.assign()获取一个对象的值副本,并断开与observable/observer的连接。你的情况会起作用吗?
Observable.zip(this.sudokuSolverService.solve(),Observable.interval(500),(obs, timer) => {return obs}).subscribe((nextBoardFields: Field[][]) => {
Object.assign(this.sudokuGame.boardFields, nextBoardFields);
});
我想这个问题在这里与您的solve
观察到的是,它并同步一气呵成发出自己的价值观。所以在同一个嘀嗒声中,您可以调用所有的onNext
,也可以调用onComplete
。因此,当zip
时,它获得第一个值,等待计时器,但在此期间,您的可观察值已经在同一个tick上发出了所有值。你可能需要做的是让你的迭代变量链接到定时器,例如:
Observable.interval(500).scan(function(_, iterationCount){
// your logic here
return {
iterationCount : iterationCount
isFinished : // your logic here
boardFields : // your logic here
}
}, {})
.doWhile(function(x){return x.iteration < 500 && !x.isFinished})
.map(function(x){return x.boardFields})
Maarek的回答让我朝着正确的方向前进。
关键的是,即使我复制了Field[][]
- 阵列与方法,如[].concat(nextBoardFields)
或Maarek的Object.assign(this.sudokuGame.boardFields, nextBoardFields)
,个人Field
的仍然指向同一个对象。
要深入复制这个数组,我使用了o.next(JSON.parse(JSON.stringify(this.sudokuGame.boardFields)))
,它允许我按照预期使用我的Observable。
我确实知道不可变也会起作用,但我同意它增加了一层复杂性,这不会很有趣。 – Maarek
你应该给出一个代码示例。 – Soviut
你是对的,编辑传入。 – Maarek