I’m starting to get pretty frustrated with Dart’s async
…
All I want is lazily load some value and assign it to a property in my class:
Future<String> getMeSomeBar() async => "bar";
class Foo {
late String bar = await getMeSomeBar();
}
this doesn’t work, of course.
But what really drives me mad is that I know Kotlin has a runBlocking
function that is designed for cases exactly like that and there just doesn’t seem to be a Dart equivalent or pattern that would allow me to do the same.
At least not one that I’ve found, so far.
I can’t even do a basic spin-lock in Dart because there’s no way to check for the state of a Future
…
So because getMeSomeBar
is outside of my control, I need to makeFoo.bar
a Future<String>
.
Which means I have to make whatever function accesses Foo.bar
an async
function.
Which means I have to make whatever functions accesses that function, an async
function.
Which means I have to make whatever functions accesses those function async
too.
Which means …
You get the point. In the end, the whole bloody app is going to be asynchronous simply because I seem to have absolutely no way to block a thread/isolate until a Future
is completed.
That can’t be the solution?!
Is there a way to avoid this?
(No, using then
doesn’t help because then you’re either waiting for the completion of that Future
– which again, you seem to only be able to do in an async
function – or you’re gambling on your Future
s’ returning "in time" – which is just plain stupid.)
2
Answers
Not sure if this is a scalable solution for you, but you could delay building your
Foo
class until the completion of aFuture<T>
, effectively creating an asynchronous factory ofFuture<Foo>
.You could then (1) use that
Future<Foo>
in aFutureBuilder
widget that listens forFuture<Foo>
to resolve before building your real layout, or (2) you could use your ownCompleter<Foo>
in a stateful widget to update the state when done.Also: if you have to await several Futures to build
Foo
, you can useFuture.all(...)
in yourFoo.fromAsyncCall
Future-factory.Here’s an example:
Alternatively, you could try to alter your class in such a way where it can complete itself in some form of late-valued fields. I wouldn’t recommend that because if you try to access
bar
before it has completed it could throw an error.