Flutter - Как мне использовать await внутри streambuilder? - PullRequest
0 голосов
/ 28 апреля 2020

Я хочу использовать await внутри streambuilder. Однако, если вы используете asyn c внутри, вы получите ошибку. По коду ниже !!!!!!!! Это часть, которую я хочу решить. Большое спасибо, если я могу рассказать вам, как.

class _MemoStreamState extends State<MemoStream> {
final _fireStore = Firestore.instance;

@override
Widget build(BuildContext context) {
return StreamBuilder<QuerySnapshot>(
  stream: _fireStore
      .collection(widget.logInUsrEmail)
      .orderBy('id', descending: false)
      .snapshots(),
  builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
    if (!snapshot.hasData) return LinearProgressIndicator();

    final memos = snapshot.data.documents;
    List<MemoMaterial> memoList = [];

    for (var memo in memos) {
      final memoDocumentID = memo.documentID;
      final memoTitle = await PlatformStringCryptor().decrypt(memo.data['title'], _key);  !!!!!!!!!!
      final memoUsrID = memo.data['usrID'];
      final memoUsrPW = memo.data['usrPW'];
      final memoText = memo.data['text'];
      final memoCreateTime = memo.data['createTime'];

      final memoMaterial = MemoMaterial(
        logInUsrEmail: widget.logInUsrEmail,
        doc: memoDocumentID,
        title: memoTitle,
        usrID: memoUsrID,
        usrPW: memoUsrPW,
        text: memoText,
        createTime: memoCreateTime,
      );
      memoList.add(memoMaterial);
    }

    return Expanded(
      child: new ListView.builder(

Ответы [ 2 ]

3 голосов
/ 28 апреля 2020

Вы должны сделать что-то вроде этого:

  Stream<List<MemoMaterial>> memosStream;

  Future<MemoMaterial> generateMemoMaterial(Memo memo) async {
    final memoTitle =
        await PlatformStringCryptor().decrypt(memo.data['title'], _key);

    return MemoMaterial(
      logInUsrEmail: widget.logInUsrEmail,
      doc: memo.documentID,
      title: memoTitle,
      usrID: memo.data['usrID'],
      usrPW: memo.data['usrPW'],
      text: memo.data['text'];,
      createTime: memo.data['createTime'],
    );
  }

  @override
  void initState() {
    memosStream = _fireStore
            .collection(widget.logInUsrEmail)
            .orderBy('id', descending: false)
            .snapshots()
            .asyncMap((documents) => Future.wait([for (var memo in memos) generateMemoMaterial(memo)]));
    super.initState();
  }
  @override
  Widget build(BuildContext context) {
  return StreamBuilder<List<MemoMaterial>>(
    stream: memosStream // Use memostream here

asyncMap() будет «преобразовывать» каждый новый набор документов в список MemoMaterial и отправлять этот список в поток при выполнении действия.

Future.wait() позволяет выполнять несколько асинхронных c запросов одновременно.

0 голосов
/ 28 апреля 2020

Вы можете сделать это с помощью FutureBuilder внутри StreamBuilder следующим образом.

Stream<List<int>> callme() async* {
    yield [1, 2, 3, 4, 5, 6];
  }

  buildwidget() async {
    await Future.delayed(Duration(seconds: 1));
    return 1;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: StreamBuilder(
            stream: callme(),
            builder: (_, sna) {
              if (sna.hasData) {
                return FutureBuilder(
                  future: buildwidget(),
                  builder: (_, snap) {
                    if (snap.hasData) {
                      return ListView.builder(
                        itemCount: sna.data.length,
                        itemBuilder: (_, index) {
                          return Text("${sna.data[index]} and ${snap.data}");
                        },
                      );
                    } else {
                      return CircularProgressIndicator();
                    }
                  },
                );
              } else {
                return CircularProgressIndicator();
              }
            }),
      ),
    );
  }
...