-
Notifications
You must be signed in to change notification settings - Fork 55
Mixing early returns with async_blocks #107
Comments
I think so. Using an async_block means the code outside of that block will be run immediately; you should only do this if you need that code to be run immediately. I don't think its true that users need to "consider asynchronicity," as you say, when inside the async block; in contrast, I think by using an async_block you are signaling to readers that they need to worry about the immediacy of the code that runs outside of it; that that code has some sort of side effect & the timing of it matters. In other words, the great ambition of async/await in Rust, with its type system, is that everything in the async will run "eventually," it doesn't matter when. |
One other consideration is whether users of this API would prefer to handle errors in the pre-async part of the code differently to the async part. Probably not in the case of a The big thing I note in your implementation is Closest I can currently see is fn foo(&self) -> impl Future<...> {
let result: Result<_, Box<Error>> = loop {
break do catch {
if let Some(early_value) = self.check() {
break Ok(Either::A(early_value));
}
let request = self.prepare_request()?;
let client = self.client.clone();
Either::B(async_block! {
let response = await!(client.make_request(request));
await!(parse(response))
})
}
};
future::result(result).flatten()
} Maybe some parts of this could be extracted out to a macro to do the early return plumbing for you? |
I realise that this isn't really about async/await itself, but using it in surrounding code made me question my instincts, so I figured I'd open a discussion...
I want to write some code along the lines of:
There are three big things that stop me from being able to do this today; the two things commented on in the code, and that my function returns an
impl Future
, but after making the two changes in the comments, I'm no longer returning one unique anonymousFuture
type, so I need toBox
everything up rather than returning animpl Trait
.My instinct is that my
async_block
should be as short as possible, because minimising the scope where the reader needs to consider asynchrony feels good. But if I'd moved the lines before the client cloning as-is into theasync_block
, the code would compile fine (modulo theself
borrows), because theasync_block
itself does effectively return aResult
.Is my instinct to minimise the size of
aync_block
s wrong? Is there a more ergonomic way of doing what I'm doing without enlarging theasync_block
?Thanks!
The text was updated successfully, but these errors were encountered: