首页 > 解决方案 > 我怎样才能等待一个变量

问题描述

是否可以在 Dart 中使用 aFutureawait更改简单变量的值?

就我而言,我有一个单例方法,在第一次调用时,它会创建并打开一个数据库。这个方法是从我的应用程序中的多个地方调用的,我需要一种方法让第二个、第三个等调用等到第一个调用创建并打开数据库。

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改变呢?好像我在这里遗漏了一些明显的东西......

标签: asynchronousflutterdartasync-awaitreactive-programming

解决方案


我发现我可以使用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

推荐阅读