I am having an hard time comparing Futures correctly in Dart. I hope I can be clear enough. I am doing two experiments:
This first test works. I create a future and then assign the same future to another variable. The Future is passed by reference so the variable is pointing at the same memory area and the objects are the same. Indeed the hashcode is the same and the comparison is true.
void main() {
Future f1 = Future.delayed(const Duration(seconds: 1));
Future f2 = f1;
print(f1.hashCode);
print(f2.hashCode);
print(f1 == f2);
}
Now, in this second test, I am doing the same operation but this time inside a method. I am trying to avoid to sending multiple calls to an API. I do one call and save the Future in a variable. When a method tries to send the request again, I pass him the pending Future instead of creating a new one. In my mind, since the Futures are passed as a reference, they should still be the same and compare to true. Instead, I get false, and the Hashcode are completely different.
void main() {
Test();
}
class Test {
Future? _future = null;
Test() {
init();
}
void init() {
print("CALL 1");
Future d1 = processFuture();
print("ISNULL? " (_future == null).toString());
print("CALL 2");
Future d2 = processFuture();
print("ISNULL? " (_future == null).toString());
print(d1.hashCode);
print(d2.hashCode);
print(d1 == d2);
}
Future processFuture() async {
print("CALLED processFuture()");
if (_future != null){
print("FUTURE IS ALREADY THERE");
return _future;
}
print("NEW FUTURE REQUESTED");
_future = Future.delayed(const Duration(seconds: 1));
print("NEW FUTURE CREATED");
await _future;
print("FUTURE COMPLETE");
_future = null;
print("FUTURE IS NOW NULL");
return;
}
}
Am I missing something? Can someone explain me what I am misunderstanding and what am I doing wrong?
Thank you very much
CodePudding user response:
in first test you have only one object from Future
and passed that to variables(f1, f2
) so object(or reference) is same.
but in second test, per call processFuture
function, a Future object will be returned, so objects(or reference) will be different
CodePudding user response:
Refactored the function to not be an async function, thanks @pskink
void main() {
Test();
}
class Test {
Future<dynamic>? _future = null;
Test() {
init();
}
void init() {
print("CALL 1");
Future<dynamic>? d1 = processFuture();
print("ISNULL? " (_future == null).toString());
print("CALL 2");
Future<dynamic>? d2 = processFuture();
print("ISNULL? " (_future == null).toString());
print(d1.hashCode);
print(d2.hashCode);
print(d1 == d2);
}
Future<dynamic>? processFuture() {
print("CALLED processFuture()");
if (_future != null){
print("FUTURE IS THERE");
return _future;
}
print("NEW FUTURE REQUESTED");
_future = Future.delayed(const Duration(seconds: 1))
.then((res) {
print("FUTURE COMPLETE");
_future = null;
print("FUTURE IS NOW NULL");
return res;
});
print("NEW FUTURE CREATED");
return _future;
}
}