2017-08-29 9 views
0

私はクライアントから2つの文字列の配列を取得し、それぞれのストリームをサーバー側に開くようにマップします。 (コード例では、実際のデータストリームの代わりにsetIntervalを使用してできるだけ単純なものにしています)。内部スコープから機能的アプローチで値を更新するにはどうすればよいですか?

また、このデータをオブジェクト内で再構成するので、更新する値を保持できます後で。 setIntervalがトリガーされるたびに、私はマップしているイテレートに対応するキーの値を増やします。

const stream = (arr) => { 

    // arr = ['firstValue', 'secondValue'] 

    // the object to store the values which will be sent to the client 
    const restructure = { 
     [arr[0]]: 0, 
     [arr[1]]: 0 
    } 

    arr.map((i) => { 
     // setInterval as a placeholder stream 
     setInterval(() => { 
      restructure[i]++ 
      // instead of logging, the updated object is sent to client 
      console.log(restructure) 
     }, 2000) 
    }) 
} 

値をバンプアップした後、更新されたオブジェクトをクライアントに送り返します。明らかにこれは機能しますが、より機能的なアプローチでこのアップデート操作を行いたいと思います。

RamdaとLodash/Fpからいくつかの方法を試しましたが、異なるスコープのオブジェクトを更新することは不可能なようです。

通常、何が起きるのかは、値がバンプされ、次の間隔で元の値に戻ることです。

内部のスコープから何らかの機能を介してこのデータを更新する実行可能な方法はありますかsetState

+3

機能的なアプローチでは、値を更新しません。新しいものを作成します。 – Bergi

答えて

3

Ramdaは、ユーザーデータを変更しないという原則に基づいて設計されています。それはあなたがRamdaを使ってそうすることができないということを意味するものではありませんが、Ramdaの機能自体はそれを助けません。これはかなり意図的です。不変のデータ構造は、関数型プログラミングの重要な概念の1つです。

あなたの例として、私が気づいた最初のことは、stream関数が何も返さないということです。ここでも、これはFPで奇妙なことです。

ここで、関数内でRamdaを使用する場合は、たとえばlet restructure = fromPairs(map(key => [key, 0], arr))を使用して開始できます。

setIntervalの中には、restructureの値をrestructure = evolve({[i]: R.inc}, restructure)などの値でリセットすることができます。一緒にすべてを置く

、我々は

再び
const stream = (arr) => { 
    let restructure = fromPairs(map(key => [key, 0], arr)); 
    R.map((key) => { 
    setInterval(() => { 
     restructure = evolve({[key]: R.inc}, restructure    
     console.log(restructure); 
    }, 2000) 
    }, arr) 

    return() => restructure 
} 

であなたの例に似たものを持っている可能性があり、RAMDAは実際の場所でその変数を更新しません。しかし、それがあなたにそれを再割り当てするのを妨げないことは確かです。

Ramda REPLでこれが少し変わることがあります。

+0

REPLのあなたの例は、私の実際のストリームをシミュレートするのにうまくやってくれます。 – cinnaroll45

関連する問題