Как реализовать async / await во Flutter - PullRequest
0 голосов
/ 05 мая 2020

У меня есть эта функция, которая выполняет некоторые firestore операции и извлекает данные.

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

Вот мой код. Я напечатал несколько операторов print, чтобы проверить порядок выполнения.


getNewsOnSearchBar() {
  final String _collection = 'news';
  final Firestore _fireStore = Firestore.instance;
  var newsList = [];

  print("1");
  getData() async {
    print("2");
    return await _fireStore.collection(_collection).getDocuments();
  }

  getData().then((val) async{
    if (val.documents.length > 0) {
      print("3");
      for (int i = 0; i < val.documents.length; i++) {        
        newsList.add(await val.documents[i].data["headline"]);
      }
    } else {
      print("Not Found");
    }
  });

  print("4");

  return ok;
}

И результат:

I/flutter (17145): 1
I/flutter (17145): 2
I/flutter (17145): 4 // 4 prints before 3
I/flutter (17145): 3

Мне нужен результат:

I/flutter (17145): 1
I/flutter (17145): 2
I/flutter (17145): 3
I/flutter (17145): 4

Кто-нибудь может мне помочь?

Ответы [ 2 ]

1 голос
/ 05 мая 2020

Вместо использования вы можете использовать ожидание, и это должно решить вашу проблему. Вот как будет выглядеть ваш код с изменениями, и я настоятельно рекомендую указать тип данных, которые будет возвращать ваша функция.

getNewsOnSearchBar() async {
    final String _collection = 'news';
    final Firestore _fireStore = Firestore.instance;
    var newsList = [];

    print("1");

    Future<QuerySnapshot> getData() async {
        print("2");
        return await _fireStore.collection(_collection).getDocuments();
    }

    QuerySnapshot val = await getData();
    if (val.documents.length > 0) {
        print("3");
        for (int i = 0; i < val.documents.length; i++) {        
           newsList.add(val.documents[i].data["headline"]);
        }
    } else {
       print("Not Found");
    }
    print("4");
    return ok;
}
1 голос
/ 05 мая 2020

Если вы хотите дождаться значения из Future, как в вашем случае, не используйте then, используйте await:

Future<int> myFunc() {
  return Future.delayed(Duration(seconds: 1), () => 0);
}

void main() async {
  final int result = await myFunc();
  print(result);//0
}

В вашем случае вы хотели бы сделать что-то подобное (вы можете изменить это по своему усмотрению):

getNewsOnSearchBar() async {
  final String _collection = 'news';
  final Firestore _fireStore = Firestore.instance;
  var newsList = [];

  print("1");
  getData() async {
    print("2");
    return await _fireStore.collection(_collection).getDocuments();
  }

  final ref = await getData();
  if (ref.documents.length > 0) {
    print("3");
    for (int i = 0; i < ref.documents.length; i++) {
      newsList.add(await ref.documents[i].data["headline"]);
    }
  } else {
    print("Not Found");
  }

  print("4");

  return ok;
}
...