I have a function loadData
that loads some text from a file:
Future<String> loadAsset() async { return await rootBundle.loadString('assets/data/entities.json'); }
The loadString
method is from Flutter SDK, and is asynchronous.
The loadAsset
method is then called in another method, that must me marked as async
, since loadAsset
is async and I need to use await
:
Future<List<Entity>> loadEntities() async { String jsonData = await loadAsset(); return parseData(jsonData); }
The parseData
method is not async, it receives a String
, parse it, and return a list of objects:
List<Entity> parseData(String jsonString) { ... }
But since loadEntities
must be marked with async
, this requires that it returns a Future
, but in practice, it's not a Future
because since I use await
, it awaits for the loadAsset
method to finish, then call the parseData
funcion using the result.
This easily turns into a snowball of async
call, because every method that uses loadEntities
must be marked as async
too.
Also, I can't use loadEntities
in a class constructor, because the constructor should be marked as async
, which is not allowed in Dart.
Am I using the async/await
pattern in Dart wrong? How could I use the loadEntities
method in a class constructor?
A simple answer for that: No, we can't! Currently, class constructors do not return types, and an asynchronous method should return a Task type.
Just call getWRitings() or whatever async method and don't await it. It won't be done when the constructor ends, but that's ok. Don't use its value there, instead - use its value in another method and call that.
You can create an async init() {... return this;} method, then instead do new MyClass(). init() whenever you'd normally just say new MyClass() .
The call to the async method starts an asynchronous task. However, because no Await operator is applied, the program continues without waiting for the task to complete. In most cases, that behavior isn't expected.
No, async is contagious and there is no way to go back from async to sync execution.
async
/await
is only syntactic sugar for methodThatReturnsFuture().then(...)
Marking a method with async
is only to allow you to use await
inside its body. Without async
you would still need to return a Future
for calling code to only execute after the result of loadAsset()
becomes available.
You can use the Future returned from the async call directly. This would look something like this:
class HasAsync { HasAsync() { asyncFunction().then((val) { print(val); }); } Future<int> asyncFunction() async { int val = await otherFunction(); return val; } }
You just can't use await within the non-async function.
As you've tagged this with 'flutter', I'm going to guess this is within a flutter app. If that's the case look at the docs for FutureBuilder - it might help with what you're trying to do.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With