Handling asynchronous programming with Ramda
I know, the question is old. But ramda has some cool functions to compose Promise-returning functions: pipeP and composeP.
Also take a look into regular compose (pipe) and it's Kleisli implementation composeK (pipeK). They allow to work with algebraic structures like Future or Task, which look the same as Promise, but lazy-evaluated.
pipeP
and composeP
got deprecated.
Create pipeWithPromise
which accepts an array of promises or functions.
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';
You can use Promise.resolve
to "wrap" a value in a promise.
getSectionFromDataPromise :: obj -> promise
getSectionFromDataPromise = R.pipe(getSectionFromData , (val) => Promise.resolve(val))
This way you can promote (lift) any function that returns a normal value to a one that returns a promise.
Lifting is an essential concept in FP. You can view Array.map
as a function that lifts a function that transforms a value to a function that transforms an array of values.
You can use Promise.all
to write a function that compares promises and (for example) throws an error if they are not equal.
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]
})
}
Lastly you can combine the two:
promiseEquals(getSectionFromDataPromise, getSectionFromDb)
.then(function(val){
console.log(val)
})
.catch(function(val){console.log("Error "+val)})