Как я могу ждать переменную - PullRequest
1 голос
/ 16 июня 2019

Можно ли использовать Future к await изменению значения простой переменной в Dart?

В моем случае у меня есть одноэлементный метод, который при первом вызове создаети открывает базу данных.Этот метод вызывается из нескольких мест в моем приложении, и мне нужен способ для второго, третьего и т. Д. Вызовов ждать, пока первый вызов не создаст и не откроет базу данных.

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 изменить?Кажется, что я упускаю что-то очевидное здесь ...

1 Ответ

3 голосов
/ 16 июня 2019

Я понял, что могу использовать 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
...