On Dart DOC site I see this example of asyncronous,
Future<void> printOrderMessage() async {
print('Awaiting user order...');
var order = await fetchUserOrder();
print('Your order is: $order');
}
Future<String> fetchUserOrder() {
return Future.delayed(const Duration(seconds: 4), () => 'Large Latte');
}
Future<void> main() async {
countSeconds(4);
await printOrderMessage();
}
void countSeconds(int s) {
for (var i = 1; i <= s; i ) {
Future.delayed(Duration(seconds: i), () => print(i));
}
}
// output
Awaiting user order...
1 // after 1 second
2 // after 2 second
3 //after 3 second
4 // after 4 second
Your order is: Large Latte // after 4 second
after I changed the code by convert return type of printOrderMessage() and main() to void and remove async and await of main() , is output the same result
printOrderMessage() async {
print('Awaiting user order...');
var order = await fetchUserOrder();
print('Your order is: $order');
}
Future<String> fetchUserOrder() {
return Future.delayed(const Duration(seconds: 4), () => 'Large Latte');
}
main() {
countSeconds(4);
printOrderMessage();
}
void countSeconds(int s) {
for (var i = 1; i <= s; i ) {
Future.delayed(Duration(seconds: i), () => print(i));
}
}
// output
Awaiting user order...
1 // after 1 second
2 // after 2 second
3 //after 3 second
4 // after 4 second
Your order is: Large Latte // after 4 second
Why we ever need to sync and await in main() and return type of Future, if show the same result ?
CodePudding user response:
The void
keyword is optional for a function that return null.
So is Future<void>
.
They can be removed without changing anything.
await
keyword will pause the execution of the async function until the awaited function return. In your example printOrderMessage()
is at the last line of main()
. It doesn't matter if it's awaited or not because there is no other code to execute after printOrderMessage() return.
If printOrderMessage
is before countSeconds
, the await
keyword will change the output :
main() async {
printOrderMessage();
countSeconds(4);
}
main() async {
await printOrderMessage();
countSeconds(4);
}
CodePudding user response:
You don't need the async
and await
in main
.
As written, it makes no difference.
It's good practice to not ignore asynchronous behavior, and using async
and await
here highlights that asynchrony is actually happening.
It doesn't matter for the behavior of this program because all the final await printOrderMessage();
does is to receive a future from printOrderMessage()
, wait for it to complete, then complete the Future
returned by main
(which it returns because of the async
) with either null
or the same error, if the awaited future completed with an error. No-one waits for the future returned by main
, so any value-result is ignore and any error becomes an uncaught async error. And that's exactly the same that would happen if you just write printOrderMessage();
without the await
- the value is ignored and the error is uncaught.
If anyone had access to the future returned by main
then you would see a difference - the main
future would complete immediately without the await
, instead of waiting, and it would not get the same errors (it can't, since it didn't wait for it). That makes main
special, as the one function that no-one ever looks at the result of, and it's better to just get in the habit of awaiting all futures instead of worrying over whether you really need so in a main
method.