为什么我的效果被调用两次?

我有用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

回到顶部