выполнить задачу Fluture с помощью Sancuary Either
У меня есть такая трубка
const asyncFn = (x) => {
return Future.tryP(() => Promise.resolve(x + ' str2'))
};
const pipeResult = S.pipe([
x => S.Right(x + " str1"), // some validation function
S.map(asyncFn),
])("X");
pipeResult.fork(console.error, console.log);
Я хочу выполнить асинхронную операцию в asyncFn
. Проблема в том, когда у меняRight
в качестве ввода я могу его форкнуть.
Когда я регистрирую pipeResult
Я вижу это:
Right (tryP(() => Promise.resolve(x + ' str2')))
Как я могу это сделать?
1 ответ
Either a b
а также Future a b
оба способны выражать неудачу / успех. При работе с асинхронными вычислениями обычно лучше использоватьFuture a b
скорее, чем Future a (Either b c)
. Более простой и плоский тип требует меньше карт:S.map (f)
скорее, чем S.map (S.map (f))
. Еще одно преимущество состоит в том, что значение ошибки всегда в одном и том же месте, тогда как сFuture a (Either b c)
обе a
а также b
представляют собой неудачные вычисления.
Однако у нас может уже быть функция проверки, которая возвращает либо. Например:
// validateEmail :: String -> Either String String
const validateEmail = s =>
s.includes ('@') ? S.Right (S.trim (s)) : S.Left ('Invalid email address');
Если у нас есть значение fut
типа Future String String
, как нам проверить адрес электронной почты fut
может содержать? Первое, что нужно попробовать, это всегдаS.map
:
S.map (validateEmail) (fut) :: Future String (Either String String)
Было бы неплохо избежать этого вложения. Для этого нам сначала нужно определить функцию изEither a b
к Future a b
:
// eitherToFuture :: Either a b -> Future a b
const eitherToFuture = S.either (Future.reject) (Future.resolve);
Теперь мы можем преобразовать функцию, возвращающую одно из двух, в функцию, возвращающую в будущем:
S.compose (eitherToFuture) (validateEmail) :: String -> Future String String
Давайте вернемся к нашему использованию S.map
:
S.map (S.compose (eitherToFuture) (validateEmail)) (fut) :: Future String (Future String String)
У нас все еще есть вложенность, но теперь оба типа - внутренний и внешний. Future String _
. Это означает, что мы можем заменитьS.map
с S.chain
чтобы не вводить гнездование:
S.chain (S.compose (eitherToFuture) (validateEmail)) (fut) :: Future String String