为什么我的效果被调用两次?
问题描述:
我有用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));
}
}
};
}
如果您在'main'中删除对'liftAff'的调用会发生什么?我不认为这是必要的。 (不要原谅这种行为,这确实看起来是错误的;我只是想诊断) – hdgarrood
没有变化。唯一有点“异国情调”的是我使用的是https://github.com/sectore/purescript-webpack-vanilla-hmr。尽管如此,它应该表现一贯(或者总是2次或者总是一次,但是在不同的订单上没有不同) – robkuz
同意。你可以通过'psc-bundle'运行上述程序并将其上传到一个pastebin? – hdgarrood