2016-08-19 6 views
2

私は与えられた数独(実装は重要ではない)に対する解を計算し、計算の各反復をRxJS Observableに公開するサービスを持っています。私は後でこの解決プロセスは私Angular2成分で人間による顕著な遅延とを通過する反復を表示するObservable.interval()オブザーバーでこれに観察を組み合わせることObservable.zip()を使用できるように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; 
} 

は、私がこれを行います。

私はそうのように私のAngular2成分で観察により放射されたデータを設定するときしかし、:

Observable.zip(this.sudokuSolverService.solve(),Observable.interval(500),(obs, timer) => {return obs}).subscribe((nextBoardFields: Field[][]) => { 
     this.sudokuGame.boardFields = nextBoardFields; 
    }); 

その後観察可能の排出が遅れているが、変更はそれにもかかわらず、即座に表示されます。これは私がnextBoardFields -Arrayを参照してコピーしたことが原因だと思われますが、boardFields --Arrayを私のsudoku-solvingサービスのAngular2-controllerのリンクとリンク解除する方法はわかりません。

これを行う可能性はありますか?

編集:どういうわけか、このことについては少し複雑だが、(おそらくImmutable.jsの助けを借りて)Fieldクラスは不変にすることです私の心に来るだけの事。

答えて

0

オブジェクトの値のコピーを取得し、オブザーバブル/オブザーバへの接続を切断するためにObject.assign()を使用しました。それはあなたの場合に働くでしょうか?

Observable.zip(this.sudokuSolverService.solve(),Observable.interval(500),(obs, timer) => {return obs}).subscribe((nextBoardFields: Field[][]) => { 
    Object.assign(this.sudokuGame.boardFields, nextBoardFields); 
}); 
+0

私も変わらないと思っていますが、それは楽しいものではない複雑さのレイヤーを追加することに同意します。 – Maarek

+0

実際にコード例を挙げてください。 – Soviut

+0

あなたは正しいです、着信を編集してください。 – Maarek

1

は、私がここにあなたのsolve観測可能に問題があることを推測することが同期して一度にその値を発することです。だから、同じティックでは、onNextと、onCompleteがあります。したがって、zipの場合、最初の値を取得し、タイマーを待機しますが、その間、観測可能な値は同じティックですべて出力されます。あなたはおそらく行う必要があることはあなたの反復変数のような、タイマーにリンクされていることです。

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}) 
0

Maarekの答えが正しい方向に私を押しました。

キーは、私は、このような[].concat(nextBoardFields)やMaarekのObject.assign(this.sudokuGame.boardFields, nextBoardFields)ような方法でField[][] -arrayをコピーした場合でも、個々のField年代はまだ同じオブジェクトを参照するというものでした。

この配列を詳細にコピーするには、o.next(JSON.parse(JSON.stringify(this.sudokuGame.boardFields)))を使用しました。これにより、Observableを意図どおりに使用することができました。

関連する問題