问题
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?
回答1:
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.
回答2:
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.
回答3:
Just a correction: async methods are NOT contagious. The Test constructor calls the async method sayHello. This demonstrates how to have a ctor make an async call when its not allowed to be declared async. The main method is marked async simply so that the application doesn't shutdown before sayHello completes. Its not an intrinsic requirement.
class Test
{
Test()
{
sayHello();
}
void sayHello() async
{
await Future.delayed(Duration(seconds: 4) , () => print("Hello"));
print("We said hello");
}
}
void main() async
{
doTest();
// wait for hello to be output
await Future.delayed(Duration(seconds: 6) , () {});
print("Ending");
}
void doTest()
{
Test();
}
来源:https://stackoverflow.com/questions/49537996/future-async-await-in-dart