admin管理员组文章数量:1425873
Background
I have a simple code that poses functions to print Hello Mars!
:
var greeting = () => "Hello ";
var dbQuery = str => Promise.resolve( `${str} Mars` );
var phrase = R.pipeP(
greeting,
dbQuery,
R.flip( R.concat )("!")
);
phrase();
Problem
I am using pipeP
because dbQuery
returns a Promise. I am under the impression that pipeP
could work if I converted my entire code to promises, but I really do want to avoid that.
My idea was to something something like flatMap
, aka chain
in Ramda, but that doesn't work either.
Question
How can I make this code work without converting everything into a Promise?
A MWE can be found here
Background
I have a simple code that poses functions to print Hello Mars!
:
var greeting = () => "Hello ";
var dbQuery = str => Promise.resolve( `${str} Mars` );
var phrase = R.pipeP(
greeting,
dbQuery,
R.flip( R.concat )("!")
);
phrase();
Problem
I am using pipeP
because dbQuery
returns a Promise. I am under the impression that pipeP
could work if I converted my entire code to promises, but I really do want to avoid that.
My idea was to something something like flatMap
, aka chain
in Ramda, but that doesn't work either.
Question
How can I make this code work without converting everything into a Promise?
A MWE can be found here
Share Improve this question asked Jan 9, 2018 at 14:07 Flame_PhoenixFlame_Phoenix 17.7k40 gold badges146 silver badges284 bronze badges 6- How about just writing it normally, without Ramda? – Ry- ♦ Commented Jan 9, 2018 at 14:10
-
1
Check discussion in this thread - as well as discussions linked in there. In short, Ramda team sees
pipeP
(andposeP
) as old way of doing things. – raina77ow Commented Jan 9, 2018 at 14:20 -
@raina77ow That could work if
greeting
was a Promise. However, it isn't. When the first value in the pipe is not a position, how could you make it work? – Flame_Phoenix Commented Jan 9, 2018 at 14:27 -
You want to pose a nullary function with an action that returns a
Promise
. This just doesn't work and Ramda is right to plain. – user6445533 Commented Jan 9, 2018 at 14:40 - I know why Ramda plains. I never said Ramda was wrong. I made that clear in my post and even suggest fixes that i don't like. – Flame_Phoenix Commented Jan 9, 2018 at 14:44
3 Answers
Reset to default 3Once you are dealing with Promise/Task/Future, there's no avoiding having to handle asynchronous data and program flow
How can I make this code work without converting everything into a Promise?
By everything, do you mean this part?
// ...
phrase();
For the same reason the ternary operator ?:
forces you to include both branches of the conditional, asynchronous calls expect you to handle both the successful and the erroneous branches of the Promise/Task/Future
// ...
phrase().then(onSuccess, onError);
Of course there's nothing stopping you from doing
const main = () =>
phrase().then(console.log, console.error)
main()
And as raina77ow mentions, pipeP (and poseP) are not remended. We can fix your program by adding a simple then
function which is easily inserted in a normal pipe
(or pose
) sequence of functions
const greeting = () => "Hello ";
const dbQuery = str => Promise.resolve( `${str} Mars` );
const then = R.curry((f, p) => p.then(f))
const phrase = R.pipe(
greeting,
dbQuery,
then(R.flip(R.concat)('!'))
);
phrase().then(console.log, console.error);
// Hello Mars!
// => { Promise 'Hello Mars!' }
<script src="https://cdnjs.cloudflare./ajax/libs/ramda/0.25.0/ramda.js"></script>
I wrote the following helper function below which should solve your problem. It deals with promise and non-promise data equally. It also checks for arrays with promises being returned and, if so, handles them with Promise.all
. As expected, its final result will be a promise.
function asyncPipe(...funcs){
const reducer = async (val, func) => func(await (Array.isArray(val) ? Promise.all(val): val));
return async val => await R.reduce(reducer, val, funcs)
}
Here is how to use asyncPipe
for your original code problem:
function asyncPipe(...funcs){
const reducer = async (val, func) => func(await (Array.isArray(val) ? Promise.all(val): val));
return async val => await R.reduce(reducer, val, funcs)
}
var greeting = () => "Hello ";
var dbQuery = str => Promise.resolve( `${str} Mars` );
var phrase = asyncPipe(
greeting,
dbQuery,
R.flip( R.concat )("!")
);
phrase().then(console.log);
Ramda now includes then and otherwise functions, so best to use these:
https://ramdajs./docs/#andThen
https://ramdajs./docs/#otherwise
本文标签: javascriptMake Rpipe work with a PromiseStack Overflow
版权声明:本文标题:javascript - Make R.pipe work with a Promise? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745403262a2657133.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论