尝试构建一个自定义的StreamTransformer类,但是很多示例似乎已经过时了,文档中找到的那个(不管怎么说有些类型的语言可能会考虑)作为一个类(见https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/dart:async.StreamTransformer)。这似乎不像是一种类似Dart的方式来接近它,而更像是一种类似Javascript的方式(我使用Dart来避免)。
许多在线消息人士都说这是你创建StreamTransformer的方式,但扩展它时会出错。
class exampleStreamTransformer extends StreamTransformer
{
//... (This won't work)
}
'器具'似乎是要走的路,同时实现所需的绑定功能:
class exampleStreamTransformer implements StreamTransformer
{
Stream bind(Stream stream)
{
//... (Go on to return new stream, etc)
}
}
我似乎无法找到这种方式的任何示例,但我自己也抛出了一些东西(我的IDE已经接受了,但是在运行时没有被接受,我得到一个null对象错误)尝试使用暂停吸气剂):
class exampleStreamTransformer implements StreamTransformer
{
StreamController<String> _controller;
StreamSubscription<String> _subscription;
Stream bind(Stream stream)
{
_controller = new StreamController<String>(
onListen: ()
{
_subscription = stream.listen((data)
{
// Transform the data.
_controller.add(data);
},
onError: _controller.addError,
onDone: _controller.close,
cancelOnError: true); // Unsure how I'd pass this in?????
},
onPause: _subscription.pause,
onResume: _subscription.resume,
onCancel: _subscription.cancel,
sync: true
);
return _controller.stream;
}
}
希望以这种方式实现这一目标,例如“键入”字样。制作课程的方式,非常感谢任何帮助,谢谢。
答案 0 :(得分:5)
为什么不使用StreamTransformer.fromHandler()
:
import 'dart:async';
void handleData(data, EventSink sink) {
sink.add(data*2);
}
void main() {
StreamTransformer doubleTransformer = new StreamTransformer.fromHandlers(handleData: handleData);
StreamController controller = new StreamController();
controller.stream.transform(doubleTransformer).listen((data) {
print('data: $data');
});
controller.add(1);
controller.add(2);
controller.add(3);
}
<强>输出强>:
data: 2
data: 4
data: 6
答案 1 :(得分:5)
好。这是另一个工作示例:
import 'dart:async';
class DuplicateTransformer<S, T> implements StreamTransformer<S, T> {
StreamController _controller;
StreamSubscription _subscription;
bool cancelOnError;
// Original Stream
Stream<S> _stream;
DuplicateTransformer({bool sync: false, this.cancelOnError}) {
_controller = new StreamController<T>(onListen: _onListen, onCancel: _onCancel, onPause: () {
_subscription.pause();
}, onResume: () {
_subscription.resume();
}, sync: sync);
}
DuplicateTransformer.broadcast({bool sync: false, bool this.cancelOnError}) {
_controller = new StreamController<T>.broadcast(onListen: _onListen, onCancel: _onCancel, sync: sync);
}
void _onListen() {
_subscription = _stream.listen(onData,
onError: _controller.addError,
onDone: _controller.close,
cancelOnError: cancelOnError);
}
void _onCancel() {
_subscription.cancel();
_subscription = null;
}
/**
* Transformation
*/
void onData(S data) {
_controller.add(data);
_controller.add(data); /* DUPLICATE EXAMPLE!! REMOVE FOR YOUR OWN IMPLEMENTATION!! */
}
/**
* Bind
*/
Stream<T> bind(Stream<S> stream) {
this._stream = stream;
return _controller.stream;
}
}
void main() {
// Create StreamController
StreamController controller = new StreamController.broadcast();
// Transform
Stream s = controller.stream.transform(new DuplicateTransformer.broadcast());
s.listen((data) {
print('data: $data');
}).cancel();
s.listen((data) {
print('data2: $data');
}).cancel();
s.listen((data) {
print('data3: $data');
});
// Simulate data
controller.add(1);
controller.add(2);
controller.add(3);
}
让我补充一些注意事项:
implements
似乎是正确的方法。答案 2 :(得分:2)
您可以使用StreamTransformer.fromHandlers轻松创建 只将输入事件转换为输出事件的变换器。
示例:
{{1}}
答案 3 :(得分:2)
与map
不同,转换器具有更强大的功能,可让您维护内部状态并在需要时发出值。它可以实现map
无法做到的事情,例如延迟,复制,省略某些值等等。
本质上,该实现需要一个bind
方法和一个cast
方法,该方法基于传入的旧流提供一个新流,该方法有助于在运行时进行类型检查。
这是实现“ TallyTransformer”的一个过分简化的示例,该“ TallyTransformer”将整数值流转换为总和流。例如,如果到目前为止输入流具有1, 1, 1, -2, 0, ...
,则输出流将是1, 2, 3, 1, 1, ...
,即,将到目前为止的所有输入相加。
用法示例:stream.transform(TallyTransformer())
class TallyTransformer implements StreamTransformer {
StreamController _controller = StreamController();
int _sum = 0; // sum of all values so far
@override
Stream bind(Stream stream) {
// start listening on input stream
stream.listen((value) {
_sum += value; // add the new value to sum
_controller.add(_sum); // emit current sum to our listener
});
// return an output stream for our listener
return _controller.stream;
}
@override
StreamTransformer<RS, RT> cast<RS, RT>() {
return StreamTransformer.castFrom(this);
}
}
此示例过于简化(但仍然可以使用),并且不涉及诸如流暂停,恢复或取消之类的情况。如果遇到"Stream has already been listened"
错误,请确保流正在广播。
答案 4 :(得分:0)
如果您只想使用类似这样的函数来转换值
SELECT_FIELDS = B.COLUMN_A INTO HOST_VAR_A
TABLE_NAME = TABLE_A A INNER JOIN TABLE_B B
ON A.ROW_ID = B.ROW_ID
WHERE_CLAUSE = A.COLUMN_B = ?
使用Stream的map方法
int handleData(int data) {
return data * 2;
}
完整示例:
stream
.map(handleData)
.listen((data) {
print('data: $data');
});
请参见dart.dev上的more examples