Open luokuning opened 6 years ago
There are full of middleware in Node.js/Express. lol... It's really powerful!
@leoyli Indeed. And if I remember correctly, the redux middleware mechanism has been inspired by Express.
那个 return funcs.reduce((a, b) => (...args) => a(b(...args))) 这段代码中的扩展运算符和展开运算符的具体作用是什么呢?我看代码调用的时候传的参数只有一个 function (arg => arg),还会出现其他什么情况么?
@EzrealPrince 是的,对于例子里的这种情况其实可以把 funcs.reduce((a, b) => (...args) => a(b(...args)))
修改成 funcs.reduce((a, b) => (fn) => a(b(fn)))
。之所以要使用 rest parameters,可能是出于一种通用情况的考虑,一般来讲函数接收的参数与返回的参数如果是一致的话(类型、个数,shape 匹配),都是可以用 compose
串联起来。
最近突然对用户的输入验证有了一些想法。
对用户的输入验证我们应该很熟悉,毕竟在提交表单的时候尤为常见。通常来说验证用户的输入并不是问题,表单内置的验证 已经可以较好的完成这个功能,但是当一个应用存在很多表单组件,而且我们想定制验证的流程与界面,每个表单的验证规则又都存在交叉时,会让验证变得比较棘手,也很容易产生一些冗余的代码。
试想一下,一个页面存在三个
input[type=text]
的输入框,分别命名为 A, B, C。为了分别验证三个表单的输入我们可能需要写三个验证函数:
这三个函数并不复杂,似乎就算是页面里再多几个类似这样的输入框,同步增加几个验证函数也能写的这么很愉快。但是仔细想想,正则表达式语义非常不清晰,稍微复杂一点的表达式通常都难以阅读,而且关键的点是输入框 A,B,C 的验证规则都相互交叉:A 跟 B 有 不为空、只能是英文字母数字或者下划线的规则,而 B 跟 C 都有关于长度限制的验证,那我们是否能把公共的验证逻辑提取出来呢?
答案是完全可以的。不过在提取之前我们先设想一下理想情况下验证用户输入的代码应该是什么样子: 我们希望每个验证的因素都是一个函数,接收一个对象作为参数,这个对象包含了需要被验证的字符的信息。每个验证函数需要对输入的数据进行处理,如果验证通过,则交由下一个验证函数处理,如果验证不通过,则返回一个新的对象,同时返回的对象里有一个
reason
属性,代表验证不通过的文字描述。代码可能如下:我们上面的代码语义非常清晰,甚至在不需要阅读每个函数源代码的情况下,只通过阅读函数名,就能知道验证了什么。而且因为函数最后返回了
reason
这个对错误的文本描述,我们可以很方便的直接把错误信息提示给用户。接下来就是实现
validate
函数与shouldLteLen
这种验证函数了。 其实我对上面函数的想法在一定程度上是受 Redux 中间件的启发。这里我们也直接利用 Redux 中的compose
函数来实现validate
函数:所以每个验证函数的写法也跟 Redux 中间件的写法类似:
通过串联验证的方式,我们可以非常方便的增减验证规则。比如我们想在上面验证的基础上增加一个必须存在下划线的规则,可以再定义一个函数
shouldContainsUnderscore
:实际使用的时候则添加为
validate
函数的参数即可:可以看到我们使用了搭积木一样的模式来对表单输入进行验证,高可定制化。实际项目中可以有若干个很小的验证中间件,通过组合的方式将它们整合为大的完整的输入验证。使用这种模式几乎可以实现在不修改旧代码而只新增代码(验证中间件)的基础上实现验证规则的增加。