Last active
July 17, 2017 17:41
-
-
Save zhangchiqing/34f299aeb96cee2dba329a9d2ff6463d to your computer and use it in GitHub Desktop.
Purescript Async
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Main where | |
import Prelude | |
import Control.Monad.Aff | |
import Control.Parallel (sequential, parallel) | |
import Control.Monad.Eff.Class (liftEff) | |
import Control.Monad.Eff (Eff) | |
import Control.Monad.Eff.Console (CONSOLE, log) | |
type A = String | |
type B = String | |
type C = String | |
type D = String | |
type E = String | |
type AffConsole e a = Aff (console :: CONSOLE | e) a | |
getA :: forall e. String -> AffConsole e A | |
getA a = do | |
liftEff $ log "getA" | |
a <- later' 2000 $ pure "A" | |
liftEff $ log "finish getA" | |
pure a | |
getB :: forall e. String -> AffConsole e B | |
getB b = do | |
liftEff $ log "getB" | |
b <- later' 1000 $ pure "B" | |
liftEff $ log "finish getB" | |
pure b | |
getCWithAB :: forall e. A -> B -> A -> AffConsole e C | |
getCWithAB a b c = do | |
liftEff $ log "getCWithAB" | |
c <- later' 1000 $ pure $ a <> b <> "C" | |
liftEff $ log "finish getCWithAB" | |
pure c | |
getDWithB :: forall e. B -> AffConsole e D | |
getDWithB b = do | |
liftEff $ log "getDWithB" | |
d <- later' 3000 $ pure $ b <> "D" | |
liftEff $ log "finish getDWithB" | |
pure d | |
getEWithCD :: forall e. C -> D -> AffConsole e E | |
getEWithCD c d = do | |
liftEff $ log "getEWithCD" | |
e <- later' 2000 $ pure $ c <> d <> "E" | |
liftEff $ log "finish getEWithCD" | |
pure e | |
-- 0 1 2 3 4 5 6 7 | |
--getA |---------> | |
--getB |----> | |
--getCWithAB |----> | |
--getDWithB |--------------> | |
--getEWithCD |--------> | |
-- Done | |
-- The above chart is the async requests flow that I want. | |
-- I want to send `getA` and `getB` together. | |
-- When both of them are finished, the results of them will be used to send `getCWithAB`. | |
-- When `getB` is finished, its result will be used to send `getDWithB` | |
-- When both `getCWithAB` and `getDWithB` are finished, the results of them will be used to send `getEWithCD` | |
-- When `getEWithCD` is finished, return the result of E. | |
-- I expect the log to be | |
-- ``` | |
-- * Build successful. | |
-- getA | |
-- getB | |
-- finish getB | |
-- getDWithB | |
-- finish getA | |
-- getCWithAB | |
-- finish getCWithAB | |
-- finish getDWithB | |
-- getEWithCD | |
-- finish getEWithCD | |
-- ABCBDE | |
-- ``` | |
-- But actually got this | |
-- ``` | |
-- * Build successful. | |
-- getA | |
-- getB | |
-- getA | |
-- finish getB | |
-- finish getA | |
-- finish getA | |
-- getCWithAB | |
-- getB | |
-- finish getCWithAB | |
-- finish getB | |
-- getDWithB | |
-- finish getDWithB | |
-- getEWithCD | |
-- finish getEWithCD | |
-- ABCBDE | |
-- ``` | |
main = launchAff do | |
let aA = getA "a" | |
let bA = getB "b" | |
let cAA = sequential $ getCWithAB <$> parallel aA <*> parallel bA <*> parallel aA | |
cA <- cAA | |
let dA = bA >>= getDWithB | |
let eAA = sequential $ getEWithCD <$> parallel cA <*> parallel dA | |
eA <- eAA | |
e <- eA | |
liftEff $ log e |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment