Reputation: 18810
Is it possible to use a Future
to await
a change of value of a simple variable in Dart?
In my case, I have a singleton method that, upon the first call, creates and opens a database. This method is being called from multiple places in my app, and I need a way for the second, third, etc. calls to wait until the first call has created and opened the database.
class DB{
static Database _db;
static Future<Database> instance() async {
if( _db == null ){
print('Creating/opening database');
_db = await createOrOpenDatabase();
}
return _db;
}
}
// Somewhere in the app
await DB.instance().doSomething();
// Meanwhile, somewhere else in the app
await DB.instance().doSomethingElse();
This results in
Creating/opening database
Creating/opening database
One way to solve this would be to add some variable that indicates that the database is currently being created and/or opened:
class DB{
static Database _db;
static bool _openingDb;
static Database instance() async {
if( _openingDb )
// Wait until _openingDb becomes false
if( _db == null ){
_openingDb = true;
print('Creating/opening database');
_db = await createOrOpenDatabase();
_openingDb = false;
}
return _db;
}
}
But just how do I wait for the value of _openingDb
to change? It seems like I'm missing something obvious here...
Upvotes: 1
Views: 55
Reputation: 18810
I figured out that I can use a Completer to accomplish what I wanted.
class DB {
static Database _db;
static Completer _dbOpenCompleter;
static Future<Database> instance() async {
if( _dbOpenCompleter != null && !_dbOpenCompleter.isCompleted ) {
print('Awaiting database creation');
await _dbOpenCompleter.future;
}
if( _db == null ) {
_dbOpenCompleter = Completer();
try {
print('Creating/opening database');
_db = await openOrCreateDatabase();
}
finally{
_dbOpenCompleter.complete();
}
}
return _db;
}
}
Now the same calls as in the original question result in the following output:
Creating/opening database
Awaiting database creation
Upvotes: 3