web-dev-qa-db-ja.com

Ramdaによる非同期プログラミングの処理

私は、pipeP以外のRamda関数でpromiseを返す関数の処理を検討しています。私は関数(そのうちの1つはpromiseを返す)を次のような等しいものと比較しようとしています:

getSectionFromDb :: obj -> promise
getSectionFromData :: obj -> number

R.equals(
    getSectionFromDb,
    getSectionFromData
)

ここでは2つの要素が関係しています。最初のR.equalsは関数を評価しませんが、より大きな問題は、promiseを数値と比較していることです。

この種のことを行う機能的な方法はありますか(関数は参照透過性ではないことは知っていますが、ioを処理する方法が必要です)?これを行うRamdaの方法はありますか?

ありがとう。

16
BBS

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)})
5
Bobby Marinoff

私は知っています、質問は古いです。しかし、ramdaには、Promiseを返す関数を構成するためのいくつかの優れた関数があります: pipeP および composeP

また、通常の composepipe )を調べてください。これはKleisliの実装 composeKpipeK )です。それらは、FutureやTaskのような代数的構造を扱うことを可能にします。これらは、Promiseと同じように見えますが、遅延評価されています。

11
Alex Yatkevich

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';
1
episage