Async / Await / затем в Dart / Flutter - PullRequest
0 голосов
/ 04 февраля 2019

У меня есть приложение для флаттера, где я использую плагин SQFLITE для извлечения данных из Sqlite db.Здесь я сталкиваюсь со странной проблемой.Насколько я понимаю, для асинхронного программирования мы используем либо функцию async / await, либо then ().Здесь у меня есть метод db.query (), который выполняет некоторый SQL-запрос для извлечения данных из БД.После того, как эта функция извлекает данные, мы выполняем некоторую дальнейшую обработку в функции .then ().Однако при таком подходе я столкнулся с некоторыми проблемами.Оттуда, где я вызываю эту функцию getExpensesByFundId (int fundId), кажется, что данные не извлекаются правильно.Он должен возвращать объект Future>, который затем будет преобразован в список, когда будут доступны данные.Но когда я звоню, это не работает.

Однако я просто поэкспериментировал с ним и добавил ключевое слово «await» перед функцией db.query (), и почему-то он просто начал работать нормально.Можете ли вы объяснить, почему добавление ключевого слова await решает эту проблему?Я думал, что при использовании функции .then () нам не нужно использовать ключевое слово await.

Вот мои коды:

Future<List<Expense>> getExpensesByFundId(int fundId) async {
    Database db = await database;

    List<Expense> expenseList = List();

   // The await in the below line is what I'm talking about

    await db.query(expTable,where: '$expTable.$expFundId = $fundId')
        .then((List<Map<String,dynamic>> expList){
      expList.forEach((Map<String, dynamic> expMap){
        expenseList.add(Expense.fromMap(expMap));
      });
    });
    return expenseList;
  }

1 Ответ

0 голосов
/ 04 февраля 2019

простыми словами:

await предназначено для прерывания потока процесса до завершения асинхронного метода.then однако не прерывает поток процесса (то есть будут выполнены следующие инструкции), но позволяет запускать код после завершения асинхронного метода.

В вашем примере вы не можете достичь того, чего хотите, когда выиспользуйте then, потому что код не «ждет», а оператор return обрабатывается и, следовательно, возвращает пустой список.

Когда вы добавляете await, вы явно говорите: «не уходите»далее, пока не будет завершен мой Future (часть then).

Вы можете написать свой код следующим образом, чтобы достичь того же результата только с await:

Future<List<Expense>> getExpensesByFundId(int fundId) async {
    Database db = await database;

    List<Expense> expenseList = List();

    List<Map<String,dynamic>> expList = await db.query(expTable,where: '$expTable.$expFundId = $fundId');
    expList.forEach((Map<String, dynamic> expMap) {
        expenseList.add(Expense.fromMap(expMap));
    });

    return expenseList;
}

YouМожно также выбрать использование только части then, но вам необходимо убедиться, что впоследствии вы правильно вызвали getExpensesByFundId:

Future<List<Expense>> getExpensesByFundId(int fundId) async {
    Database db = await database;

    List<Expense> expenseList = List();

    return db.query(expTable,where: '$expTable.$expFundId = $fundId')
        .then((List<Map<String,dynamic>> expList){
      expList.forEach((Map<String, dynamic> expMap){
        expenseList.add(Expense.fromMap(expMap));
      });
    });
}

// call either with an await
List<Expense> list = await getExpensesByFundId(1);
// or with a then (knowing that this will not interrupt the process flow and process the next instruction
getExpensesByFundId(1).then((List<Expense> l) { /*...*/ });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...