Future<void> vs void - flutter

Say I want to create an asynchronous method. I can make its return type either Future void or simply "void" (as in examples below). Both ways seem to do the trick. So what's the difference between the two? When should I use Future void instead of void? Thanks!
Future<void> myMethod() async{
await myOtherMethod(); //myOtherMethod() has return type of Future<void>
print('something');
}
vs
void myMethod() async{
await myOtherMethod(); //myOtherMethod() has return type of Future<void>
print('something');
}

Use Future<void> where you want to
Call future functions:
myMethod().then((_) => ...).catchError((err) => ...);
Use await for more readable async code.
await myMethod();
await anotherMethod();
Use void where you want to fire and forget.
myMethod();
... do other stuff
The Future<void> is a lot more common. If you're not sure which one to use, use Future<void>.

Future<void> myMethod() async{ }
is a asynchronous function which means it let the app to work while waiting for some operation to finish(ex:Network Request).The Future fun(); is used while we need to perform operation that gives result in future such as network call.
void fun(){};
is function that doesnot return anything.

Related

Flutter Riverpod Future provider - requires async and await?

I've been reviewing the RiverPod 2 tutorial at https://codewithandrea.com/articles/flutter-state-management-riverpod/
In the section dealing with Future providers there is a code snippet as shown below...
final weatherFutureProvider = FutureProvider.autoDispose<Weather>((ref) {
// get repository from the provider below
final weatherRepository = ref.watch(weatherRepositoryProvider);
// call method that returns a Future<Weather>
return weatherRepository.getWeather(city: 'London');
});
I can't understand why this code snippet is missing the 'async' and 'await' syntax as shown below...
final weatherFutureProvider = FutureProvider.autoDispose<Weather>((ref) async {
// get repository from the provider below
final weatherRepository = ref.watch(weatherRepositoryProvider);
// call method that returns a Future<Weather>
return await weatherRepository.getWeather(city: 'London');
});
Is my version correct or what?
Think of it as doing:
Future<int> example() {
return Future.value(42);
}
instead of:
Future<int> example() async {
return await Future.value(42);
}
Sure, you can use async/await. But it is technically optional here.
Doing return future vs return await future doesn't change anything. In fact, there's a lint for removing the unnecessary await: unnecessary_await_in_return
The async keyword is generally helpful. It catches exceptions in the function and converts them into a Future.error.
But FutureProvider already takes care of that. So async could also be omitted

Most elegant way to wait for async initialization in Dart

I have a class that is responsible for all my API/Database queries. All the calls as well as the initialization of the class are async methods.
The contract I'd like to offer is that the caller has to call [initialize] as early as possible, but they don't have to await for it, and then they can call any of the API methods whenever they need later.
What I have looks roughly like this:
class MyApi {
late final ApiConnection _connection;
late final Future<void> _initialized;
void initialize(...) async {
_initialized = Future<void>(() async {
// expensive initialization that sets _connection
});
await _initialized;
}
Future<bool> someQuery(...) async {
await _initialized;
// expensive async query that uses _connection
}
Future<int> someOtherQuery(...) async {
await _initialized;
// expensive async query that uses _connection
}
}
This satisfies the nice contract I want for the caller, but in the implementation having those repeated await _initialized; lines at the start of every method feel very boilerplate-y. Is there a more elegant way to achieve the same result?
Short of using code-generation, I don't think there's a good way to automatically add boilerplate to all of your methods.
However, depending on how _connection is initialized, you perhaps instead could change:
late final ApiConnection _connection;
late final Future<void> _initialized;
to something like:
late final Future<ApiConnection> _connection = _initializeConnection(...);
and get rid of the _initialized flag. That way, your boilerplate would change from:
Future<bool> someQuery(...) async {
await _initialized;
// expensive async query that uses `_connection`
to:
Future<bool> someQuery(...) async {
var connection = await _connection;
// expensive async query that uses `connection`
This might not look like much of an improvement, but it is significantly less error-prone. With your current approach of using await _initialized;, any method that accidentally omits that could fail at runtime with a LateInitializationError when accessing _connection prematurely. Such a failure also could easily go unnoticed since the failure would depend on the order in which your methods are called. For example, if you had:
Future<bool> goodQuery() async {
await _initialized;
return _connection.doSomething();
}
Future<bool> badQuery() async {
// Oops, forgot `await _initialized;`.
return _connection.doSomething();
}
then calling
var result1 = await goodQuery();
var result2 = await badQuery();
would succeed, but
var result2 = await badQuery();
var result1 = await goodQuery();
would fail.
In contrast, if you can use var connection = await _connection; instead, then callers would be naturally forced to include that boilerplate. Any caller that accidentally omits the boilerplate and attempts to use _connection directly would fail at compilation time by trying to use a Future<ApiConnection> as an ApiConnection.

Call for a definite value from an async method in flutter. waiting problem

How to write a function which fetches value from an async method ?
Future FetchValuefromService(String tk) async{ await .. //Fetch from api return value; }
void mainfunction(){ double newval =FetchValuefromService('hello'); //.... do something with newval. }
if i make mainfunction() async then the "do something" in mainfucntion will not get the double value. I need to get newval from service and then only i need to proceed.
Making a function async ables to use the await keyword in its body. Place it to the left of a Future<T> expression to pause the execution until the Future completes and the T value is obtained.
In your case, it would be double newval = await FetchValuefromService('hello');

Flutter Future<void> vs Future<Null> vs void

What is the main difference between:
Future<void> function(){}
Future<Null> function(){}
void function() {}
funtion(){}
Sometimes I use void or future when calling the API but I don't really know what the main difference is and when is the right time to use it?
Future<void> function() {}
Defines an asynchronous function that ultimately returns nothing but can notify callers when it eventually completes. Also see: What's the difference between returning void vs returning Future?
Future<Null> function() {}
Defines an asynchronous function that ultimately returns null when it eventually completes. Don't use this; this is an archaic form of Future<void>. It predates Dart 2 and was necessary because void was not yet a proper type, and there was no mechanism for indicating that a Future should return nothing. Also see: Dart 2: Legacy of the void
void function() {}
Defines a function that returns nothing. If the function does asynchronous work, callers will not be able to directly tell when it is complete.
function() {}
Defines a function with an unspecified return type. The return type is implicitly dynamic, which means that the function can return anything. Don't do this since it does not convey intent; readers will not be able to tell if the return type was omitted intentionally or accidentally. It also will trigger the always_declare_return_types lint. If you actually want to return a dynamic type, you should explicitly use dynamic function() {} instead.
By default, a function likes function() {} returns a null pointer value.
Use this archetype when your function not return anything and it's not marked as async:
function() { // <- not async
// ... some code
// ... don't use return
}
Optionally, you can specify not return values using void function() {} sintaxis. It's same at the function() {} but if you try to assign a value after calling you will get an error in compile time:
Error: This expression has type 'void' and can't be used.
Personally, i recommend this approach if you really don't have a return value and the function it's not async.
Note that you can use void in normal and async functions.
A function likes Future<void> function() async {} is for asynchronous function thats returns a Future<void> object.
I personally recommend the void function() async {} only if you don't use await ot then on call your function, otherwise, use Future <void> function() async {}.
An examples:
Future<void> myFunction() async {
await Future.delayed(Duration(seconds: 2));
print('Hello');
}
void main() async {
print(myFunction()); // This works and prints
// Instance of '_Future<void>'
// Hello
// Use this approach if you use this:
myFunction().then(() {
print('Then myFunction call ended');
})
// or this
await myFunction();
print('Then myFunction call ended');
}
void myFunction() async {
await Future.delayed(Duration(seconds: 2));
print('Hello');
}
void main() async {
print(myFunction()); // This not works
// The compile fails and show
// Error: This expression has type 'void' and can't be used.
// In this case you only can call myFunction like this
myFunction();
// This doesn't works (Compilation Error)
myFunction().then(() {
print('Then myFunction call ended');
});
// This doesn't works (Compilation Error)
await myFunction();
print('Then myFunction call ended');
}
A function likes Future<Null> function() async {} returns a Future<null> object. Use it whenever you return null. It's not recommended to use it because class Null not extends from Object and anything you return marks an error (except statements thats returns a null or explicit null value):
Future<Null> myFunction() async {
await Future.delayed(Duration(seconds: 2));
print('Hello');
// Ok
return (() => null)();
// Ok
return null;
}

Is there a difference whether using await with return in Dart?

In my flutter project, say there's a foo(int x) async function. And bar() async that looks like:
Future bar() async {
return foo(3);
}
The bar() function is just a simple capsule for foo(int x) with a certain parameter. And bar() is used as the future in a FutureBuilder.
I'm not sure if I should use await with return. I can't find related documentations online. So what's the difference between return foo(3) and return await foo(3)? Thank you!
No difference whatsoever.
Technically, using await first might wait for the Future to resolve before returning from the function, but you won't be able to tell the difference.
A Future is returned either way.
The async there is useless too, it might as well just be an arrow:
Future bar() => foo(3);
If it were not the last statement, and a return statement, this could matter, as pointed out in the comments, take the following:
Future bar() async {
try {
return await foo(3);
} catch(error) {
return baz;
}
}
If foo rejects, then it matters quite a lot, as it would be handled by the callee, not the caller.
Since you are returning Future, in this exact case, even if you don`t await it, the foo(3) will return Future instead and it is the exact thing your function wants to return. and if u await it there, then it will await in the function and then return the value.
you don`t even need await in this case if foo return Future. Then the caller of bar will instead await the bar.
Using this simple example you can see in which order prints yield:
Future<void> fetchUserOrder() {
return Future.delayed(const Duration(seconds: 2), () => print('Large Latte'));
}
void main() async {
await fetchUserOrder();
print('Fetching user order...');
}
fetchUserOrder() returns Future. So if we call it in main with await, it will receive the Future, execute it and await for the result. Only then proceed to the second print of the main.
We could've written the fetchUserOrder() in such a fashion:
Future<void> fetchUserOrder() async {
return await Future.delayed(const Duration(seconds: 2), () => print('Large Latte'));
}
And it wouldn't have had changed the result. It would work the same, the only difference is shorter code and that now you understand how it works.
Use https://dartpad.dev/ to launch these examples.