You probably can't do that with multiple async blocks, since every async block generates its own, unique, and distinct impl Future type, just like every closure generates its own impl Fn(…) -> … type.
What you can do is introduce concrete and identical types for the generators, e.g. by relying on dyn Future. Here's a playground. But I think that's outright disgusting, especially in the light of the simple solution provided by @Hyeonu.
By design, each async block has a unique type, which is incompatible with all other types of async blocks. An async block is not a piece of code to be executed, but a struct with a state machine inside, so async { 0 } is not returning a 0, it returns a unique Future-like object.
OTOH Code like unwrap_or requires the type in the option and the alternative to be exactly the same type.
You could unify types of async blocks via type erasure (BoxFuture), but that adds runtime overhead and unnecessary layer of abstraction to jam them into a helper function that wasn't designed to handle async at all.