Флаттер: почему этот метод не работает?

#flutter #dart

#Флаттер #дротик

Вопрос:

В QuerySnapshot у него есть «Day1» и «Day2», которые являются днями недели, такими как «Суббота». Если «Day1» или «Day2» сегодня, мне нужно вернуть «true». Но этот метод всегда возвращает false . Мне нужно знать, почему условие If (в цикле) не работает и как я могу это решить?

 bool class_count(Stream<QuerySnapshot> stream) {
  bool class_ = false;
  String dateFormat = DateFormat('EEEE').format(DateTime.now());
  //This Line Return Day Like "Saturday"
  stream.forEach((element) {
    if (element != null) {
      for (int count = 0; count < element.documents.length; count  ) {
        if (element.documents[count].data['Day1'].toString() == dateFormat)
          class_ = true;
        if (element.documents[count].data['Day2'].toString() ==
            dateFormat) if (element.documents[count].data['Day2']
                .toString() ==
            dateFormat) class_ = true;
      }
    }
  });
  print(class_);
  return class_;
}


 

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

1. Я немного обновил свой ответ.

Ответ №1:

Потому что поток forEach является асинхронным. Таким образом, этот цикл не будет ждать завершения. В вашем коде вы устанавливаете class_ значение false , затем создаете a future , которое будет выполняться в будущем, и classs_ сразу возвращаете. Так что он по-прежнему равен false .

Попробуйте добавить async суффикс к методу и await перед stream.forEach ним . И тогда ваш метод должен возвращать Future<bool> и вызываться как

 final class = await class_count(someStream);
 

Я думаю, что лучший способ обработки событий потока — добавить прослушиватель для потока и обработать в нем данные.

 stream.listener((event) {
  // here must be your code which will be executed each time stream will get event
});
 

Ответ №2:

stream.forEach() метод возвращает значение будущего типа. Итак, вы должны вызвать этот метод внутри другой асинхронной функции, а также его нужно ожидать до завершения этого будущего.

Решение:-

  • Преобразуйте ваш class_count() синхронный метод в асинхронный с помощью,
    1. Добавление async ключевого слова в заголовок метода.
    2. Измените возвращаемый тип на a Future<bool> .
  • Добавьте await ключевое слово перед stream.forEach() вызовом метода (асинхронная операция).

Код:-

[Внимательно прочитайте комментарии, чтобы правильно понять ход программы]

 //1- Return type should be a Future type => Future<bool>.
//2- Add async keyword before method body => async.
Future<bool> class_count(Stream<QuerySnapshot> stream) async{
  bool class_ = false;
  String dateFormat = DateFormat('EEEE').format(DateTime.now());

  //3 - Adding await keyword before asynchronous operation => await.
  //
  await stream.forEach((element) {
    if (element != null) {
      for (int count = 0; count < element.documents.length; count  ) {
        if (element.documents[count].data['Day1'].toString() == dateFormat)
          class_ = true;
        if (element.documents[count].data['Day2'].toString() ==
            dateFormat) if (element.documents[count].data['Day2']
                .toString() ==
            dateFormat) class_ = true;
      }
    }
  });
  //After stream.forEach() method completes its loop these below statements will execute.
  //Every statements inside the function body will only execute one after another.
  //so below statements are only executes after the above operation completes.
  print(class_);
  return class_;
}
 

Один дополнительный совет: — Используя StreamSubcription, вы можете получать потоки данных вместо future.