asynchronous - 我怎样才能等待一个变量
问题描述
是否可以在 Dart 中使用 aFuture
来await
更改简单变量的值?
就我而言,我有一个单例方法,在第一次调用时,它会创建并打开一个数据库。这个方法是从我的应用程序中的多个地方调用的,我需要一种方法让第二个、第三个等调用等到第一个调用创建并打开数据库。
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();
这导致
Creating/opening database
Creating/opening database
解决此问题的一种方法是添加一些变量来指示当前正在创建和/或打开数据库:
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;
}
}
但是我该如何等待价值_openingDb
改变呢?好像我在这里遗漏了一些明显的东西......
解决方案
我发现我可以使用Completer来完成我想要的。
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;
}
}
现在,与原始问题相同的调用会产生以下输出:
Creating/opening database
Awaiting database creation
推荐阅读
- scala - 如何在 spark scala 中覆盖特定的表分区
- c++ - C++ 将日、月、年转换为毫秒
- sqlite - 在db中查找重复的列多个值
- javascript - PHP Mailer 返回 PHP 致命错误:未捕获 PHPMailer\PHPMailer\Exception:SMTP 错误:无法验证
- regex - 如何为我的列表使用正则表达式
在颤振/飞镖? - reactjs - 无法使用 axios 网络错误 reaxt 原生于 heroku 发布
- java - 如何反序列化杰克逊中嵌套的包装字符串?
- javascript - 如何在 Excel 电子表格中添加文件?
- python - 在这个程序中,window = Tk() 的功能是什么,因为忽略它会给出相同的输出
- node.js - NodeJS / Multer:如何用新文件替换目录中的现有文件