- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在使用Folktale的Validation在一个新项目上,我发现它确实很有用,但我在需要顺序验证方面遇到了困难。我有一个配置对象,我需要执行以下验证:
每次验证都取决于之前的验证 - 如果该项目不是对象,则验证其键是毫无意义的(并且会出错),如果该对象没有键,则验证其值是毫无意义的。实际上,如果验证失败,我想短路验证。
我最初的想法是使用 Result而不是 Validatio,但混合这两种类型感觉很困惑,而且我已经在其他地方定义并使用了
validateIsObject`。
我当前的(有效但丑陋)解决方案在这里:
import { validation } from 'folktale';
import { validateIsObject } from 'folktale-validations';
import validateConfigKeys from './validateConfigKeys';
import validateConfigValues from './validateConfigValues';
const { Success, Failure } = validation;
export default config => {
const wasObject = validateIsObject(config);
let errorMessages;
if (Success.hasInstance(wasObject)) {
const hadValidKeys = validateConfigKeys(config);
if (Success.hasInstance(hadValidKeys)) {
const hasValidValues = validateConfigValues(config);
if (Success.hasInstance(hasValidValues)) {
return Success(config);
}
errorMessages = hasValidValues.value;
} else {
errorMessages = hadValidKeys.value;
}
} else {
errorMessages = wasObject.value;
}
return Failure(errorMessages);
};
我最初采用了使用嵌套 matchWith
的方法,但这更难阅读。
如何改进此解决方案?
最佳答案
您可以编写一个助手来应用验证规则,直到返回Failure
。一个简单的例子:
const validateUntilFailure = (rules) => (x) => rules.reduce(
(result, rule) => Success.hasInstance(result)
? result.concat(rule(x))
: result,
Success()
);
我们使用concat
来组合两个结果。我们使用 Success.hasInstance
来检查是否需要应用下一条规则。您的模块现在将只有一行:
export default config => validateUntilFailure([
validateIsObject, validateConfigKeys, validateConfigValues
]);
请注意,一旦发现失败
,此实现就不会提前返回。递归实现可能是更实用的方法,但不会吸引所有人:
const validateUntilFailure = ([rule, ...rules], x, result = Success()) =>
Failure.hasInstance(result) || !rule
? result
: validateUntilFailure(rules, x, result.concat(rule(x)))
查看下面的示例以了解运行代码。有一个注释掉的部分显示了如何运行所有规则,即使存在失败。
const { Success, Failure } = folktale.validation;
const validateIsObject = (x) =>
x !== null && x.constructor === Object
? Success(x)
: Failure(['Input is not an object']);
const validateHasRightKeys = (x) =>
["a", "b"].every(k => k in x)
? Success(x)
: Failure(['Item does not have a & b.']);
const validateHasRightValues = (x) =>
x.a < x.b
? Success(x)
: Failure(['b is larger or equal to a']);
// This doesn't work because it calls all validations on
// every item
/*
const validateItem = (x) =>
Success().concat(validateIsObject(x))
.concat(validateHasRightKeys(x))
.concat(validateHasRightValues(x))
.map(_ => x);
*/
// General validate until failure function:
const validateUntilFailure = (rules) => (x) => rules.reduce(
(result, rule) => Success.hasInstance(result)
? result.concat(rule(x))
: result,
Success()
);
// Let's try it out!
const testCases = [
null,
{ a: 1 },
{ b: 2 },
{ a: 1, b: 2 },
{ a: 2, b: 1 }
];
const fullValidation = validateUntilFailure([
validateIsObject,
validateHasRightKeys,
validateHasRightValues
]);
console.log(
testCases
.map(x => [x, fullValidation(x)])
.map(stringifyResult)
.join("\n")
);
function stringifyResult([input, output]) {
return `input: ${JSON.stringify(input)}, ${Success.hasInstance(output) ? "success:" : "error:"} ${JSON.stringify(output.value)}`;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/folktale/2.0.1/folktale.min.js"></script>
关于javascript - Folktale 的嵌套验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48174364/
我一直在使用Folktale的Validation在一个新项目上,我发现它确实很有用,但我在需要顺序验证方面遇到了困难。我有一个配置对象,我需要执行以下验证: 是一个对象吗? 对象的 key 是否有效
背景 我正在阅读文档的每一寸内容,并尽可能多地了解 Folktale。最近,我决定尝试Future . 我们需要 future 吗? 现在我明白了 Task 和 Promise 之间以及 Task 和
我想将 id 列表转换为 Tasks 列表,并同时运行它们,类似于 Promise.all。我知道应用程序,但我想应用未知数量的任务,因此我认为这不是最好的方法。 假设我有一个 Task,其中包含 T
在 data.task 包中,我可以按如下方式解析或拒绝 api 调用: import Task from 'data.task'; import fs from 'fs'; const readFi
我一直在探索 folktale库并找到了大量有用的结构。通过 control.async 使用任务后和 data.task ,我想使用 IO monad,但似乎找不到。鉴于民间故事的丰富程度,我很惊讶
我是一名优秀的程序员,十分优秀!