Я использую трубку для проверки ввода для входа в систему, и я хотел бы по возможности разорвать и вернуть текущие данные. Возможно ли даже разбить и вернуть данные из reduce
?
Мой текущий пример кода:
const pipe = (...fns) => fns.reduce((f, g) => (obj) => g(f(obj)))
pipe(
(obj) => {
console.log('fn1', obj)
return { ...obj, ...(!!obj.name || { error: ['NAME_IS_FALSEY'] })}
},
(obj) => {
// if ((obj || {}).error ) return obj
console.log('[fn2]', obj)
return {
...obj,
...(
!!obj.password ||
obj.error ?
{ error: [...obj.error, 'PASSWORD_IS_FALSEY'] } :
{ error: 'PASSWORD_IS_FALSEY' }
)
}
},
(obj) => console.log('[fn3 etc...]', obj)
)({
name: '',
password: '',
})
Может быть, я могу обернуть все в new Promise
и разрешить на полпути через редуктор?
Вот пример рекурсивного канала, который разбивает цепочку вызовов, как только текущее значение не соответствует предикату:
const pipeWhile = pred => (f, ...fs) => x =>
pred(x) && f
? pipeWhile (pred) (...fs) (f(x))
: x;
Возможно, было бы легче прочитать сохранение, когда оно будет написано как регулярное while
или for
цикла.
Здесь он используется с вашим примером:
const pipeWhile = pred => (f, ...fs) => x =>
pred(x) && f
? pipeWhile (pred) (...fs) (f(x))
: x;
const noError = x => !x.hasOwnProperty("error");
const rule = (error, pred) => x => pred(x)
? x : { ...x, error: [error] }
const validation = pipeWhile(noError)(
rule("NAME_IS_FALSEY", obj => !!obj.name),
rule("PASSWORD_IS_FALSEY", obj => !!obj.password)
);
console.log(
validation({
name: '',
password: '',
}),
validation({
name: 'Jane',
password: '',
}),
validation({
name: 'Jane',
password: 'PA$$W0RD',
})
)
Если каждый шаг в вашей трубе возвращает объект Maybe, вы можете использовать функцию pipeK из Ramda, чтобы создать трубку на основе композиции Kleisli, которая выполняется до тех пор, пока один из шагов не вернет Nothing. Вы можете получить реализацию из святилища - возможно, пакет.
Maybe
, ОП хочет какую-то монаду / моноид Error
. Он, кажется, уже использует один, не замечая.
.errror
исключения (или проверки ваших.errror
s), нет. Вместоreduce
используйте простой цикл, если вы хотите использовать операторbreak
или рекурсию. Нет, не используйте обещания, здесь нет ничего асинхронного!