flutter StreamGroup.merge仅返回一个流

ekqde3dh  于 2023-02-25  发布在  Flutter
关注(0)|答案(1)|浏览(154)

我显然误解了StreamGroup.merge的工作原理或者stream的工作原理,或者两者都误解了!我有两个流在firestore中查询同一个字段。我使用merge创建了一个名为mergedStream的流。它在streamBuilder中使用,为应用程序提供服务。以下是我的代码:

Stream<List<Order>> stream1({Order order})  {
    return _service.collectionStream(
        path: APIPath.orders(),
        queryBuilder: (query) =>
            query.where('orderStatus', isEqualTo: 'Pending'),
        builder: (documentSnapshot) => Order.fromFirebase(documentSnapshot));
  }

  Stream<List<Order>> stream2({Order order})  {
     return _service.collectionStream(
        path: APIPath.orders(),
        queryBuilder: (query) =>
            query.where('orderStatus', isEqualTo: 'Preparing'),
        builder: (documentSnapshot) => Order.fromFirebase(documentSnapshot));
  }

和我用于流构建器的合并流:

Stream<List<Order>> mergedStream() {
    final s1 = preparingStream();
    final s2 = pendingStream();
    return StreamGroup.merge([s2, s1]);
  }

切换[s2, s1]的顺序会改变显示的流。当页面加载时,我会暂时看到另一个流,但它会消失,另一个流会出现。我如何合并这些流?
编辑:我添加flutter标记是因为它周围的阅读可能是problemStreamBuilder
编辑:这有一点帮助:(评论中的链接,只是一个概念证明,流合并)但流searchResult()不更新时,有一个他流的状态变化...你必须刷新浏览器。

Stream<List<Order>> searchResult() {
    List<Stream<List<Order>>> streamList = [stream1(), stream2()];

    var x = Rx.merge(streamList).scan<List<Order>>((acc, curr,i) {
      return acc ?? <Order>[]
        ..addAll(curr);
    });
    //this test shows that the stream gets contents from both query streams
    // x.map((convert){ convert.documents.forEach((f){print(f.data["name"]);});}).listen(print);

    return x;
  }
wgeznvg7

wgeznvg71#

StreamGroup.merge将这些流合并为一个统一的流,但它不合并每个流的内容,因此您实际上看到的是流1或流2的内容一个接一个地出现。
我建议使用StreamZip,它组合了两个流的内容,然后将其作为新值发送(第一个列表包含每个流发送的第一个值,第二个列表包含第二个值,依此类推)。

Stream<List<List<Order>>> mergedStream() {
    final s1 = preparingStream();
    final s2 = pendingStream();
    return StreamZip([s2, s1]);
  }
//This will give you a List with all the emmited values of each stream, in this case a List of List<Order>

如果您想使用包Rx,我建议使用ZipStreamCombineLatestStream

import 'package:rxdart/rxdart.dart';

Stream<List<Order>> get combineList{
  final s1 = preparingStream();
  final s2 = pendingStream();
  return ZipStream.zip2<<List<Order>>, <List<Order>>, <List<Order>>>(
    s1, s2, (firstOrder, secondOrder) => <Order>[...firstOrder, ...secondOrder]); //here you combine both in a list
}

Zip和合并之间的区别在于Zip在执行操作之前等待所有内部流发射(s1的第一个发射值和s2的第一个发射值,依此类推),而combine不关心顺序,如果您发射s1和s2的第3个之一,则它将执行[s1.1, s2.1] [s1.1, s2.2] ...

相关问题