Reputation: 1475
Consider these 3 versions
async {
return! retrieved =
client
|> get tagIdOfQid None
|> Async.Catch
|> Async.map (function
| Choice1Of2 doc ->
doc
|> mapDoc
|> function
| IdOfQ d -> d
| _ -> defaultTagIdOfQ
| _ -> defaultTagIdOfQ)
}
async {
return retrieved =
client
|> get tagIdOfQid None
|> Async.Catch
|> Async.RunSynchronously
|> function
| Choice1Of2 doc ->
doc
|> mapDoc
|> function
| IdOfQ d -> d
| _ -> defaultTagIdOfQ
| _ -> defaultTagIdOfQ)
}
async {
let! retrieved =
client
|> get tagIdOfQid None
|> Async.Catch
return! retrieved
|> function
| Choice1Of2 doc ->
doc
|> mapDoc
|> function
| IdOfQ d -> d
| _ -> defaultTagIdOfQ
| _ -> defaultTagIdOfQ
}
I want to pipe the result of the get
to another computation, I can use Async.map
, Async.RunSynchronously
or add multiple let!
bindings.
I see them all as valid alternatives for doing the same, without any differences, but maybe I'm wrong and they are doing slightly different things.
Is there any tradeoff between Async.map
, Async.RunSynchronously
and let!
?
Upvotes: 0
Views: 237
Reputation: 243126
The key difference is that if you use Async.RunSynchronously
, even if this is inside another async
workflow, this will block a thread when you run it. Using Async.map
will not block and multiple let!
is the same in this respect.
So, I would avoid using Async.RunSynchronously
. As to what else to do, this is a style preference.
Using async { return! e }
does not make sense, because it means exactly the same as just e
, so you can simplify the first approach. I also replaced the confusing (to me at least) inner pipe with ordinary match
:
client
|> get tagIdOfQid None
|> Async.Catch
|> Async.map (function
| Choice1Of2 doc ->
match mapDoc doc with
| IdOfQ d -> d
| _ -> defaultTagIdOfQ
| _ -> defaultTagIdOfQ)
In the second approach, I would also remove some of the pipelines, because I find them hard to follow. If you are inside async
you can also use ordinary try ... with
instead of Async.Catch
:
async {
try
let! doc = get tagIdOfQid None client
match mapDoc doc with
| IdOfQ d -> return d
| _ -> return defaultTagIdOfQ
with _ -> return defaultTagIdOfQ
}
If I was writing this, I would go with the latter - mainly because it is very easy to read & understand what is going on.
Upvotes: 3