私は、pipeP以外のRamda関数でpromiseを返す関数の処理を検討しています。私は関数(そのうちの1つはpromiseを返す)を次のような等しいものと比較しようとしています:
getSectionFromDb :: obj -> promise
getSectionFromData :: obj -> number
R.equals(
getSectionFromDb,
getSectionFromData
)
ここでは2つの要素が関係しています。最初のR.equalsは関数を評価しませんが、より大きな問題は、promiseを数値と比較していることです。
この種のことを行う機能的な方法はありますか(関数は参照透過性ではないことは知っていますが、ioを処理する方法が必要です)?これを行うRamdaの方法はありますか?
ありがとう。
Promise.resolve
を使用して、promiseの値を「ラップ」できます。
getSectionFromDataPromise :: obj -> promise
getSectionFromDataPromise = R.pipe(getSectionFromData , (val) => Promise.resolve(val))
このようにして、通常の値を返す関数をpromiseを返す関数に昇格(リフト)することができます。
リフティングはFPの重要な概念です。 Array.map
は、値を変換する関数を値の配列を変換する関数に持ち上げる関数と見なすことができます。
Promise.all
を使用して、promiseを比較し、(たとえば)それらが等しくない場合にエラーをスローする関数を作成できます。
function promiseEquals (f1, f2) {
return Promise.all([f1(), f2()]).then(function(vals) {
if(!R.equals(vals[0], vals[1])) {throw "The values aren't equal"}
return vals[0]
})
}
最後に、2つを組み合わせることができます。
promiseEquals(getSectionFromDataPromise, getSectionFromDb)
.then(function(val){
console.log(val)
})
.catch(function(val){console.log("Error "+val)})
pipeP
およびcomposeP
は非推奨になりました。
Promiseまたは関数の配列を受け入れるpipeWithPromise
を作成します。
var pipeWithPromise = R.pipeWith((fun, previousResult) => (previousResult && previousResult.then) ? previousResult.then(fun) : fun(previousResult));
var tasks = [/* sync func */ $ => $ + '1', /* async func */ async $ => await $ + '2'];
var result = await pipeWithPromise(tasks)('state');
// result = 'state12';