javascript - Ramda:有没有办法在管道期间将参数“分叉”到两个函数?
问题描述
我是一个函数式编程初学者。我正在使用 Ramda 开发一个 React Native 应用程序。该应用程序允许用户维护他们的房屋。
我已经编写了一个名为的函数asyncPipe
,它让我可以管道承诺和正常函数。我将它用于loginFlow
当前有一个 http 请求 ( getHouseList
) 作为其最后一个函数。
const asyncPipe = (...fns) => x => fns.reduce(async (y, f) => f(await y), x);
const loginFlow = asyncPipe(
// ... someFunctions
getHouseList
);
// used later like this in LoginForm.js's handleSubmit():
const list = await loginFlow(credentials);
因此,登录后,应用程序会加载用户的房屋。现在,根据他是只有一所还是多栋房屋,我想将用户发送到列表视图以选择房屋,或者如果他只有一所房屋,则发送到详细视图。此外,我想发送一个 Redux 操作来将列表保存在我的 reducer 中,如果只有一个,我想发送另一个操作来挑选房子。
目前我这样做:
const list = await loginFlow(credentials);
dispatch(addHouses(list));
if (list.length > 1) {
navigate('ListScreen')
} else {
dispatch(pickHouse(list[0]);
navigate('DetailScreen') ;
}
但正如你所看到的,这是非常必要的。似乎我必须“分叉”列表并在管道中使用它两次(因为 Reduxdispatch
没有返回值)。
我的主要问题是:
如何以更具功能性/声明性的方式执行此操作(如果有办法)?
我的一个小问题是,在这里是否可以强制执行/如果执行它是一个好主意。
解决方案
您可能可以使用以下方式扩展您的异步管道tap
:
const loginFlow = asyncPipe(
// ... some functions
getHouseList,
tap(compose(dispatch, addHouses)),
tap(unless(list => list.length > 1, list => dispatch(pickHouse(list[0])))),
list => navigate(list.length > 1 ? 'ListScreen' : 'DetailScreen', list)
);
这是否值得做将取决于您的应用程序。如果管道已经很长,那么以这种方式将内容添加到末尾可能会更干净,即使它们不是特别实用的部分。但对于较短的管道,这可能没有多大意义。
您可能还想查看现已弃用的pipeP或其替代品pipeWith
( then
)。
但是您在标题中询问了有关分叉参数的问题。Ramdaconverge
正是这样做的:
converge(f, [g, h])(x) //=> f(g(x), h(x))
这也允许您传递两个以上的函数,并将多个参数传递给结果函数:
converge(f, [g, h, i])(x, y) //=> f(g(x, y), h(x, y), i(x, y))
推荐阅读
- mysql - SQL 检查是否存在非唯一记录——如果存在,则更新;如果不是,则将记录插入表中
- node.js - Heroku 在尝试使用 https 时出现“连接关闭且没有响应”错误
- c# - 如何将位于应用程序部分 (DLL) 中的部分视图呈现到主 asp.net core 2.2 项目中
- node.js - 将数据从 EJS 中的 Span 发送到服务器 Nodejs
- java - 在java中以模式打印数组
- python-requests - python - 如何在多进程池中回收来自单个requests.Session对象的请求的连接?
- acumatica - 网格内的字段过滤器
- css - 无法弄清楚为什么当 div 折叠时我的 div 内的内容会被挤压
- javascript - 网页在 Axios GET 响应之前加载
- amazon-cognito - 尝试使用 Amazon Cognito 登录应用程序时出现验证错误