2017-08-29 19 views
0

我有一個情況,我從一個客戶端得到兩個字符串的數組,並且我在它們上面映射,在服務器端爲它們中的每個打開一個流。 (在代碼示例中,我使用的是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) 
    }) 
} 

並且在將值提高後,我將更新的對象發送回客戶端。很顯然這個工作,但我想用更實用的方法來做這個更新操作。

我已經嘗試了拉姆達和Lodash/Fp的一些方法,但它似乎不可能從不同的範圍更新對象。

通常情況下發生的是值碰撞,然後他們回到他們在下一個時間間隔的原始值。

是否有一種可行的方式,通過某種功能setState從內部範圍更新此數據?

+3

在功能方法中,您不更新值。你創造新的。 – Bergi

回答

3

拉姆達非常注重從不修改用戶數據的原則。這並不意味着你不能使用拉姆達,但拉姆達功能本身並不會幫助你做到這一點。這是非常有意的;不可變數據結構是函數式編程的重要概念之一。

至於你的例子,我注意到的第一件事是你的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

相關問題