为什么我的效果被调用两次?
我有用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






