#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