在这篇文章中,我发现了这个看起来非常优雅的Elixir代码:
conn
|> put_session(:current_user, user)
|> put_resp_header(location, "/")
|> put_resp_content_type("text/html")
|> send_resp(302, "You are being redirected")它使用每个函数的输出作为下一个函数的第一个参数。给定的args被绑定到第二个参数和向上。
我知道关于管道操作员的两种不同的建议正在考虑将来的版本,但是<#>I想知道是否有一种方法可以用今天的Javascript来写一些视觉上和功能上类似的东西?
我想我可以用某种意义上的赛跑,约束除了第一个论点以外的一切?
作为参考,以下是本文中的原始函数定义。他们都返回一个conn
assign(conn, key, value)clear_session(conn)put_resp_content_type(conn, content_type, charset)put_resp_header(conn, key, value)put_session(conn, key, value)send_resp(conn, status, body)我试着提出了一些建议,但我想要输入如何改进这一点/更易读/看起来更好的普通程序员来修改我的代码。
使用ES5.1的基本尝试如下所示:
const {bind, flow} = require('lodash');
const _ = bind.placeholder;
flow(
bind(put_session, null, _, current_user, user),
bind(put_resp_header, null, _, location, '/'),
bind(put_resp_content_type, null, _, 'text/html'),
bind(send_resp, null, _, 302, 'You are being redirected')
)(conn);与原作相比,它有点冗长,所以我试着把它压缩一些:
// bind all but first argument - what should I call this?
// bindAllButFirstArgument is a tad bit long
const $ = (...args) => bind(args[0], null, _, args.slice(1));
flow(
(put_session, current_user, user),
#qcStackCode#(put_resp_header, location, '/'),
(put_resp_content_type, 'text/html'),
#qcStackCode#(send_resp, 302, 'You are being redirected')
)(conn);这看起来要好一些(除了神秘的$ : ),只要做一些小小的修改,我就可以尝试在语法上突出这个函数,比如
$(put_session, current_user, user),看起来像
pipe.prepare(put_session)(current_user, user),其中pipe相当于flow和pipe.prepare,这是一个为上面提到的管道流“准备”函数的实用函数。好些了吗?你觉得这个怎么样?太浓了?需要多读JSDocs吗?不同的方式?
会像这样
const pipe = (...args) => flow(...args);
pipe.prepare = fn => (...args) => bind(fn, null, _, args);
pipe(
pipe.prepare(put_session)(current_user, user),
pipe.prepare(put_resp_header)(location, '/'),
pipe.prepare(put_resp_content_type)('text/html'),
pipe.prepare(send_resp)(302, 'You are being redirected')
)(conn);发布于 2019-08-15 15:49:02
它使用每个函数的输出作为下一个函数的第一个参数。给定的args被绑定到第二个参数和向上。
只要按照这个描述运行,就可以轻松地创建一个带有2个助手函数的管道操作:
const bind = (fn, ...boundArgs) => callArg => fn(callArg, ...boundArgs)
const pipe = (...fns) => initialArg => fns.reduce((r, fn) => fn(r), initialArg)
pipe(
bind(put_session, current_user, user),
bind(put_resp_header, location, '/'),
bind(put_resp_content_type, 'text/html'),
bind(send_resp, 302, 'You are being redirected')
)(conn)bind接受一个函数和绑定参数,并返回一个接受单个参数的函数。当这个返回的函数被调用时,它首先用调用参数调用绑定函数,然后是绑定参数的其余部分。
pipe接受绑定函数的列表,并逐个调用它们。第一个函数获得调用参数,而其余函数获得以前调用的函数的返回值。
这种方法有效地复制了提交人的签名,但不需要提交。它也不处理this。第二个例子很简洁,而第三个例子则不那么臃肿。
https://codereview.stackexchange.com/questions/225971
复制相似问题