Я использую канал для проверки ввода для входа в систему, и я хотел бы, если возможно, разбить и вернуть текущие данные. Можно ли вообще сломать и вернуть данные с reduce?
Мой текущий пример кода:
const pipe = (...fns) => fns.reduce((f, g) => (obj) => g(f(obj)))
pipe(
(obj) => {
console.info('fn1', obj)
return { ...obj, ...(!!obj.name || { error: ['NAME_IS_FALSEY'] })}
},
(obj) => {
// if ((obj || {}).error ) return obj
console.info('[fn2]', obj)
return {
...obj,
...(
!!obj.password ||
obj.error ?
{ error: [...obj.error, 'PASSWORD_IS_FALSEY'] } :
{ error: 'PASSWORD_IS_FALSEY' }
)
}
},
(obj) => console.info('[fn3 etc...]', obj)
)({
name: '',
password: '',
})
Может быть, я могу обернуть все в new Promise и решить на полпути через редуктор?
Ты прав. Бросок однозначно сработает!



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вот пример рекурсивного канала, который прерывает цепочку вызовов, как только текущее значение не соответствует предикату:
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.info(
validation({
name: '',
password: '',
}),
validation({
name: 'Jane',
password: '',
}),
validation({
name: 'Jane',
password: 'PA$$W0RD',
})
)Если каждый шаг в вашем конвейере возвращает объект Maybe, вы можете использовать функцию pipeK из Ramda для создания канала на основе композиции Kleisli, который выполняется до тех пор, пока один из шагов не вернет Nothing. Вы можете получить реализацию из пакета sanctuary-Maybe.
Или, скорее, чем Maybe, OP хочет какую-то монаду / моноид Error. Кажется, он уже использует один, не замечая этого.
Кроме генерирования исключения (или проверки ваших
.errror), нет. Вместоreduceиспользуйте простой цикл, если вам нужен операторbreakили рекурсия. Нет, не используйте обещания, здесь нет ничего асинхронного!