为什么我的效果被调用两次?
我有用Eff
s和Aff
s编写的以下程序。按预期运行。这是它打印出给定的Int
,它做了异步计算。为什么我的效果被调用两次?
type JsonResponse = AffjaxResponse Json access :: forall e m. Aff (ajax :: AJAX | e) (Either Error JsonResponse)
access = attempt $ get "http://localhost:8080/livesys/Robert"
staging :: forall e. Int -> Eff (console :: CONSOLE | e) Int
staging i = do
liftEff $ log $ ">>" ++ show i
return i
main :: forall a. Int -> Aff (ajax :: AJAX, console :: CONSOLE| a) Int
main state = do
s <- liftEff $ staging state
a <- liftAff access
return s
如果我改变调用但内部秩序main
然后神秘的东西发生了:
main :: forall a. Int -> Aff (ajax :: AJAX, console :: CONSOLE| a) Int main state = do
a <- liftAff access
s <- liftEff $ staging state
return s
功能staging
现在被称为两次!武汉理工大学?
有人可以解释一下吗?
感谢您的帮助
回答:
很可能的情况下的异常被抛出,而不是通过处理误差函数在AFF实例。这会导致在与attempt
一起使用时重复调用成功功能。
module Main where import Prelude
import Data.Either (Either(..))
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Console (log)
import Control.Monad.Eff.Exception (Error, EXCEPTION, throwException, error)
import Control.Monad.Aff (Aff, makeAff, liftEff', launchAff, attempt)
raise = throwException <<< error
myAff :: forall e. Aff e String
myAff = _unsafeInterleaveAff $ makeAff doIt
where
doIt _ success = do
log "operation"
raise "it's dead jim"
success "done"
main = do
launchAff $ do
liftEff' $ log "start"
myAff
foreign import _unsafeInterleaveAff :: forall e1 e2 a. Aff e1 a -> Aff e2 a
此代码导致doIt
被调用两次,但是当Aff调用被颠倒时不会。
附加:
虽然这个功能似乎有点奇怪。也许用更多这样的替代attempt
?
exports._attempt = function (Left, Right, aff) { return function(success, error) {
var affCompleted = false;
try {
return aff(function(v) {
affCompleted = true
success(Right(v));
}, function(e) {
affCompleted = true
success(Left(e));
});
} catch (err) {
if (affCompleted) {
throw err;
} else {
success(Left(err));
}
}
};
}
以上是 为什么我的效果被调用两次? 的全部内容, 来源链接: utcz.com/qa/261724.html