Dartlang ‘await’ не ждет?

#asynchronous #dart #async-await

#асинхронный #dart #асинхронный -ожидание

Вопрос:

Теперь я действительно запутался с async / await.

Моя проблема (я сделал несколько комментариев в коде) :

 Future<List<TabEntry>> getLinkStructure() async {
    _log.finest("getLinkStructure called");

    String stringData = await _db.getByKey("structure");
    if (stringData == null) {
        _log.finest("No Structure saved in database - create default structure");
        List<TabEntry> structure = [];
        structure.add(new TabEntry("Home"));

        //All things are working till here

        //Problem: Create key in db - this apparently does not wait 
        String key = await _db.save(serializeToJson(structure), "structure");

        //I EXPECT THE FOLLOWING LOG NEXT

        _log.finest("dbKey: $key");
        if (key == "structure")
            return structure;
        else
            throw "Error while saving default Home tab in structure";
        }

    var data = deserialize(stringData);

    //INSTEAD I GET THIS LOG

    _log.finer("data: ${data}");        
   return data;
}
  

Как указано в исходном коде, я ожидаю увидеть (в таком порядке):

  • Вызывается getlink-структура
  • В базе данных не сохранена структура — создайте структуру по умолчанию
  • dbKey: структура (будет возвращена, если сохранение прошло успешно

Но вместо этого я получаю последний журнал dbkey

  • данные: ЭКЗЕМПЛЯР TabEntry

и тогда

  • Error with storage initialization: Invalid argument: null во внешней функции

Почему await _db.save(serializeToJson(structure), "structure") не ждет?

Редактировать:

Итак, это функция _db.save, которая используется:

 @override
Future save(String obj, String key) {
    return _runInTxn((store) => store.put(obj, key));
}
  

И это _runInTxn(…):

 Future _runInTxn(Future requestCommand(idb.ObjectStore store),
         [String txnMode = 'readwrite']) async {
var trans = _db.transaction(storeName, txnMode);
var store = trans.objectStore(storeName);
var result = await requestCommand(store);
await trans.completed;
return resu<
  

}

Комментарии:

1. Возможно save(...) (или далее по строке какой-то метод) выполняет некоторый асинхронный вызов и не ожидает его (или неправильно связывается с .then(...) ?

2. хммм, итак, save(...) это метод, которого следует ожидать. Итак, теоретически проблема может заключаться в том, что какая-то функция внутри save(...) возвращает future, но выполняет его позже? Так что мое ожидание возвращается, но внутреннее будущее не было запущено? -> эта функция сохранения поступает из библиотеки lawndart от sethladd’а.

3. serializeToJson(...) это синхронный вызов, это не должно быть проблемой

4. Но _db.save() сам по себе также может выполнять асинхронные вызовы и возвращаться до их завершения.

5. Итак, я добавил содержимое вызова _db.save в свой пост. Но, с моей точки зрения, в этом нет ничего плохого, не так ли? В любом случае, у вас есть хорошая идея, как предотвратить подобные проблемы, не углубляясь в библиотечный код?

Ответ №1:

По какой-то причине проблема с оператором await исчезла. Но, поскольку у меня были подобные случаи раньше, я буду наблюдать за этим в будущем и посмотрю, есть ли какая-то ошибка ожидания.

Вы можете найти дальнейшее обсуждение этой проблемы / о решении проблемы null (*) по адресу

https://github.com/dart-lang/sdk/issues/27469

(*) проблема с нулевым значением: Error with storage initialization: Invalid argument: null