I'm trying to create a promise or async/await version of transducers. I'm not sure if the transducers should have promises in them or not, but I do know that I need to create an async compose version. I have tried every single possible combination, but nothing works for me.
Here is a synchronous version of compose/transducers:
// Compose function
const compose = (...fns) => initialValue => fns.reduceRight((acc, fn) => fn(acc), initialValue);
// Map and Filter transducers
const mapTransducer = transform => reducer => (acc, value) => reducer(acc, transform(value));
const filterTransducer = predicate => reducer => (acc, value) => predicate(value) ? reducer(acc, value) : acc;
// Reducers for Array.reduce
const concatReducer = (acc, value) => acc.concat(value); // Could create push reducer for efficiency, but it doesn't matter at this point.
// Client Usage
const arr = [1, 2 3];
const results = arr.reduce(
compose(
filterTransducer(x => x > 1)
)(concatReducer),
[]
);
// results: [2, 3]
Async version (incomplete):
const asyncCompose = (...fns) => {
return initialValue => {
return fns.reduceRight(async (promise, fn) => {
const results = await promise; // the result of the promise is concatReducer
// fn is the filterTransducer
return fn(results);
}, Promise.resolve(initialValue));
}
};
// or
const asyncCompose = (...fns) => {
return initialValue => {
return fns.reduceRight((promise, fn) => {
return promise.then(fn) // but this doesn't make sense because the fn is filterTransducer, which isn't the same signature of promise.then method
}, Promise.resolve(initialValue));
}
};
// Client Usage
const arr = [1, 2, 3];
const results = arr.reduce(
asyncCompose(
filterTransducer(x => x > 1)
)(concatReducer),
Promise.resolve([])
);
I tried both and one at a time with no results. Transducers are difficult to wrap my head around. When composing functions, the order of the functions being executed is from right-to-left. However, with Array.reduce and transducers, the order changes.