尽管通过 Stream 发送,StreamBuilder 的快照没有数据
Posted
技术标签:
【中文标题】尽管通过 Stream 发送,StreamBuilder 的快照没有数据【英文标题】:StreamBuilder's snapshot doesn't have data despite sending it through Stream 【发布时间】:2020-04-16 06:51:30 【问题描述】:TL;DR:添加到 StreamSink
的值由于某种未知原因被受尊敬的 StreamBuilder 的 initialValue
覆盖
从表面上看,我的问题类似于 Github 上的 this 问题,但唯一的区别是,我在控制台日志中看到两条语句,而不是获取单个值,其中一条具有正确的值,已添加到流,紧随其后的是传递给流构建器的 initialValue。
就我而言,我使用的是generic_bloc_provider
细化
我有一个块 udhariBloc.dart(第 99 行),它侦听集合引用并将值添加到一些接收器。
void _fetchUdhari()
Firestore.instance
.collection("Users 3.0")
.document("data")
.collection("udhari")
.where("participants", arrayContains: userBloc.phoneNumber)
.where("firstPartyDeleted", isEqualTo: false)
.snapshots()
.listen((QuerySnapshot snapshot)
//Initialized these to zero because their
//value must be recalculated upon every change.
//These variables were initialized to zero(their default value) when declared.
_udhariList = List<UdhariClass>();
_totalDebit = 0;
_totalCredit = 0;
for (int i = 0; i < snapshot.documents.length; i++)
_udhariList.add(UdhariClass.fromSnapshot(
snapshot: snapshot.documents[i],
userBloc: userBloc,
));
// Remove the udhari records where the participant is secondParty
// and secondParty has already deleted the record
_udhariList.removeWhere((UdhariClass udhari)
return ((udhari.partyType == PartyType.SecondParty) &&
(udhari.secondPartyDeleted == true));
);
for (int i = 0; i < _udhariList.length; i++)
if (_udhariList[i].udhariType == Udhari.Borrowed)
_totalDebit += _udhariList[i].amount;
else
_totalCredit += _udhariList[i].amount;
//The correct values are calculated correctly,
//printed and added to respective sinks as well
print("Debit: $_totalDebit");
print("Credit: $_totalCredit");
print("List: $_udhariList[0].context");
_totalDebitSink.add(_totalDebit);
_totalCreditSink.add(_totalCredit);
_udhariListSink.add(_udhariList);
);
这里是流和它们的控制器
/// Stream controller for displaying total debit on dashboard
StreamController<double> _totalDebitController =
StreamController<double>.broadcast();
Stream<double> get totalDebitStream => _totalDebitController.stream;
StreamSink<double> get _totalDebitSink => _totalDebitController.sink;
/// Stream controller for displaying list of udhari
StreamController<List<UdhariClass>> _udhariListController =
StreamController<List<UdhariClass>>.broadcast();
Stream<List<UdhariClass>> get udhariListStream =>
_udhariListController.stream;
StreamSink<List<UdhariClass>> get _udhariListSink =>
_udhariListController.sink;
/// Stream controller for displaying total credit on dashboard
StreamController<double> _totalCreditController =
StreamController<double>.broadcast();
Stream<double> get totalCreditStream => _totalDebitController.stream;
StreamSink<double> get _totalCreditSink => _totalDebitController.sink;
这是我使用上述流的流构建器
StreamBuilder<double>(
initialData: udhariBloc.getTotalDebit,
stream: udhariBloc.totalDebitStream,
builder: (BuildContext context,
AsyncSnapshot<double> snapshot)
print(
"============INSIDE DEBIT STREAM BLDR============");
print("Conn State: $snapshot.connectionState");
print("Has Data: $snapshot.hasData");
print("Data: $snapshot.data");
print("Has Error: $snapshot.hasError");
print("Error: $snapshot.error\n\n");
return Text("₹$snapshot.data.floor()",
style: _textStyleFooter);
,
),
这些接收器随后在 Dashboard.dart(第 145 行)内的 streamBuilders 中使用。问题是,即使将数据添加到各个接收器(在本例中为 _totalDebitSink
),这些值也不会在 Dashboard
类内的流构建器中更新。为了进一步调查,我在 UdhariBloc 的构造函数中的 _totalDebitStream
上附加了一个侦听器
totalDebitStream.listen((onData)
print("CURRENT DEBIT: $onData");
, onError: (error)
print("Error listening Debit :$error");
, onDone: ()
print("Done listening to Debit values");
);
而且每次值发生变化时,我都会在控制台看到这个日志。
CURRENT DEBIT: 100
CURRENT DEBIT: 0
============INSIDE DEBIT STREAM BLDR============
Conn State: ConnectionState.active
Has Data: true
Data: 0.0
Has Error: false
Error: null
这里,100
是来自 Firestore 的更新值,0
是提供给 StreamBuilder 并分配给变量 _totalDebit
、_totalCredit
的初始值。
我在 dashboardBloc.dart(第 88 行)和 Dashboard.dart(第 212 行)中使用了类似的技术,效果非常好。
到目前为止,我还没有找到任何解决方案。
【问题讨论】:
我尝试在消费者类 (Dashboard.dart) 的构建方法中附加一个侦听器,并看到了类似的结果,即首先侦听器立即打印正确的值,然后是默认的初始化值。没有变化 请看更新后的代码"Here, 100 was the updated value from Firestore and 0 was the initialValue which was provided to the StreamBuilder"
- 什么StreamBuilder
?现在进行测试,您只使用低级的Stream.listen
那么StreamBuilder
是什么意思?
初始值是指变量_totalDebit
的值,初始化为零。
检查Stream<double> get totalCreditStream => _totalDebitController.stream; StreamSink<double> get _totalCreditSink => _totalDebitController.sink;
【参考方案1】:
终于找到了解决办法。原来这是我的一个愚蠢的错误。 我不小心将错误的流和接收器映射到了错误的控制器。 在这种情况下,
Stream<double> get totalCreditStream => _totalDebitController.stream;
StreamSink<double> get _totalCreditSink => _totalDebitController.sink;
这里我不小心将totalCredtiStream
映射到debitController
的流。
另外,感谢@pskink 指出。
【讨论】:
以上是关于尽管通过 Stream 发送,StreamBuilder 的快照没有数据的主要内容,如果未能解决你的问题,请参考以下文章
如何通过发送带有 application/octet-stream 内容类型的“POST”请求使用 python 将视频上传到 Microsoft 服务
EventSource / 服务器通过 Nginx 发送的事件
如果没有发送任何内容,Stream.Read不会返回任何内容
Jmeter入门13 jmeter发送application/octet-stream二进制流数据