#dart #flutter
#dart #флаттер
Вопрос:
Я сохраняю все данные API в кеше. некоторые API содержат более 10000 данных. Время ответа Postman составляет одну секунду. но в приложении очень медленно переходить на следующую страницу. Я использовал этот код:
onPressed: () async {
...
}
else {
var token = Token(
id: 1,
token: tokens,
refreshToken: model.data.refreshToken,
);
await storeRegister(_url,tokens);
await storeEquipmentReg(_url,tokens);
await storeSyncLogin(_url,tokens);
await HelperDefCatMaster().deleteDefCatMaster();
await storeDefCatMaster(_url,tokens);
await HelperDefRegisterCat().deleteDefRegisterCat();
await storeDefRegisterCat(_url,tokens);
await HelperDefCatMaster().deleteDefCatRelation();
await storeDefCatRelation(_url,tokens);
await HelperDefCatMaster().deleteWoDescription();
await storeWoDescription(_url,tokens);
await HelperDefCatMaster().deleteCategoryDefect();
await storeCategoryDefect(_url,tokens);
await storeWorkSource(_url,tokens);
await storeWorkTypes(_url,tokens);
await storePriorities(_url,tokens);
await Helper().insert(token);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ListPage(model.data.token)));
}
Функция storePriorities выглядит следующим образом,
storePriorities(String url, String token) async {
final response = await http.get(
'${url}/v1.0/Priorities',
headers: {'Authorization': 'Bearer ${token}'},
);
final jsonResponse = json.decode(response.body);
Priorities model = Priorities.fromJson(jsonResponse);
int length = model.data.length;
for (int i = 0; i < length; i ) {
var data = DataPriorities(
i: model.data[i].i,
d: model.data[i].d,
);
await HelperDefCatMaster().insertPriorities(data);
}
}
Комментарии:
1. Что такое HelperDefCatMaster?
2. это помощник базы данных. создайте базу данных, создайте таблицы и отобразите значения
Ответ №1:
Я дал первый ответ, который предлагает использовать await
только тогда, когда это необходимо.
Ну, если вы вставляете слишком много данных в SQLite, я предполагаю, что вы можете использовать что-то вроде этого:
for (int i = 0; i <= 1000; i ) {
db.insert('table_name', dataObject.toMap());
}
Ну, это будет выполнять много транзакций одновременно, и это займет много вашего времени.
Измените это на что-то вроде этого, и это увеличит скорость вставки данных:
Batch batch = db.batch();
for (int i = 0; i <= 1000; i ) {
batch.insert('table_name', dataObject.toMap());
}
await batch.commit();
Что мы здесь делаем, так это то, что в одной транзакции мы делаем несколько вставок одновременно.
Я внес это изменение в свой демонстрационный проект, где я вставлял 1000 строк за раз, и результаты были отличными. db.insert при вызове 1000 раз занимал 7 секунд, тогда как batch.insert занимал менее 1 секунды для вставки того же объема данных.
Если вы оптимизируете свой код с помощью этого решения и используете await, когда это необходимо, вы не должны сталкиваться с какими-либо проблемами в пользовательском интерфейсе. Дайте мне знать, если это поможет.
Комментарии:
1. wow..It работает хорошо. после проверки качества я сообщу вам фактический результат
2. @kapesh, могу ли я использовать транзакцию для получения данных? Я имею в виду, будет ли это более быстрая операция?
Ответ №2:
- Вы используете
await
ключевое слово для извлечения данных из SQLite. - И вы получаете много данных.
- Это сделает выборку данных синхронной и повлияет на ваш пользовательский интерфейс.
- Если для вашего варианта использования удобно извлекать данные асинхронно, вы можете использовать следующий способ:
Изменить :
await Helper().insert(token);
Navigator.push(
context,MaterialPageRoute(builder: (context) => ListPage(model.data.token)));
Для :
Helper().insert(token).then((onValue) {
Navigator.push(context,MaterialPageRoute(
builder: (context) => ListPage(model.data.token),
),
);
}
Примечание: сделайте так, чтобы ваш insert
метод возвращал Future<'token's return type'>
Теперь используйте этот способ для всех других await
вызовов.
Комментарии:
1. как это сделать:
await storeWoDescription(_url,tokens); await HelperDefCatMaster().deleteCategoryDefect(); await storeCategoryDefect(_url,tokens); Navigator.pop(context); Navigator.push( context, MaterialPageRoute( builder: (context) => ListPage(model.data.token)));
2. как использовать все остальные вызовы await?
3. Главное — не использовать await, когда вы не хотите выполнять синхронную работу.. все ли эти вызовы await необходимы для выполнения по порядку??
4. нет, но данные отсутствуют при переходе на следующую страницу.
5. после перехода на следующую страницу и ожидания 10 минут данные поступают