Dart 中等待和监听的区别
Difference between await for and listen in Dart
我正在尝试创建网络服务器流。这是代码:
import 'dart:io';
main() async {
HttpServer requestServer = await HttpServer.bind(InternetAddress.LOOPBACK_IP_V4, 8000);
requestServer.listen((request) { //comment out this or the await for to work
request.response
..write("This is a listen stream")
..close();
});
await for (HttpRequest request in requestServer) {
request.response
..write("This is an await for stream")
..close();
}
}
监听和等待有什么区别?它们不能同时工作。您需要注释掉一个或另一个才能工作,但这里的功能似乎没有区别。在某些情况下是否存在差异,什么时候应该使用一个而不是另一个?
鉴于:
Stream<String> stream = new Stream<String>.fromIterable(['mene', 'mene', 'tekel', 'parsin']);
然后:
print('BEFORE');
stream.listen((s) { print(s); });
print('AFTER');
产量:
BEFORE
AFTER
mene
mene
tekel
parsin
鉴于:
print('BEFORE');
await for(String s in stream) { print(s); }
print('AFTER');
产量:
BEFORE
mene
mene
tekel
parsin
AFTER
stream.listen()
设置代码,当事件到达时将其放入事件队列,然后执行以下代码。
await for
在事件之间挂起并一直这样做 直到流完成 ,因此在完成之前不会执行后面的代码。
我使用 `await 是因为我知道我有一个流会有有限的事件,我需要在做任何其他事情之前处理它们(基本上就像我正在处理一个期货列表)。
检查 https://www.dartlang.org/articles/language/beyond-async 以获得对 await for
的描述。
主要区别在于之后有代码。 listen
仅注册处理程序并继续执行。 await for
将保持执行直到流关闭。
因此,如果您在 main
的末尾添加一个 print('hello');
,您不应该在带有 await for
的输出中看到 hello (因为请求流永远不会关闭)。 Try the following code on dartpad 查看差异:
import 'dart:async';
main() async {
tenInts.listen((i) => print('int $i'));
//await for (final i in tenInts) {
// print('int $i');
//}
print('hello');
}
Stream<int> get tenInts async* {
for (int i = 1; i <= 10; i++) yield i;
}
一个更重要的区别是 await for
序列化流项目的消费,而 listen
将同时处理它们。
例如下面的代码:
import 'dart:async';
Future<void> process(int i) async {
print("start $i");
await new Future.delayed(const Duration(seconds: 1));
print("end $i");
}
main() async {
await for (final i in tenInts) {
await process(i);
}
tenInts.listen((i) async => await process(i));
print('hello');
}
Stream<int> get tenInts async* {
for (int i = 1; i <= 10; i++) yield i;
}
产量
start 1
end 1
start 2
end 2
start 3
end 3
start 4
end 4
start 5
end 5
start 6
end 6
start 7
end 7
start 8
end 8
start 9
end 9
start 10
end 10
hello
start 1
start 2
start 3
start 4
start 5
start 6
start 7
start 8
start 9
start 10
end 1
end 2
end 3
end 4
end 5
end 6
end 7
end 8
end 9
end 10
另一个区别是 listen()
returns 您的 StreamSubscription
对象,可以在以后的任何时间点用于 cancel/pause 订阅。您可以设置为每个数据事件或错误事件以及流关闭时调用的回调。
下面演示的是听流5秒后取消。
Stream<int> gen() async* {
for (int i = 1; i <= 10; i++) {
await Future.delayed(Duration(seconds: 1));
yield i;
}
print("done");
}
main() async {
Stream<int> stream = gen();
var subscription = stream.listen((item){
print(item);
});
await Future.delayed(Duration(seconds: 5));
subscription.cancel();
print("Exit");
}
Output:
1
2
3
4
Exit
正如罗布森所说:
await for serializes the consumption of the stream items while listen
will process them concurrently.
我还想补充一点,如果使用 pause 和 resume 方法,虽然使用 listen 方法可以逐个处理流事件。
暂停方法应该在第一个 await 关键字之前调用。
StreamSubscription<int> subscription;
subscription = tenInts.listen((i) async {
subscription.pause();
await process(i);
subscription.resume();
});
Future<void> process(int i) async {
print("start $i");
await new Future.delayed(const Duration(seconds: 1));
print("end $i");
}
我正在尝试创建网络服务器流。这是代码:
import 'dart:io';
main() async {
HttpServer requestServer = await HttpServer.bind(InternetAddress.LOOPBACK_IP_V4, 8000);
requestServer.listen((request) { //comment out this or the await for to work
request.response
..write("This is a listen stream")
..close();
});
await for (HttpRequest request in requestServer) {
request.response
..write("This is an await for stream")
..close();
}
}
监听和等待有什么区别?它们不能同时工作。您需要注释掉一个或另一个才能工作,但这里的功能似乎没有区别。在某些情况下是否存在差异,什么时候应该使用一个而不是另一个?
鉴于:
Stream<String> stream = new Stream<String>.fromIterable(['mene', 'mene', 'tekel', 'parsin']);
然后:
print('BEFORE');
stream.listen((s) { print(s); });
print('AFTER');
产量:
BEFORE
AFTER
mene
mene
tekel
parsin
鉴于:
print('BEFORE');
await for(String s in stream) { print(s); }
print('AFTER');
产量:
BEFORE
mene
mene
tekel
parsin
AFTER
stream.listen()
设置代码,当事件到达时将其放入事件队列,然后执行以下代码。
await for
在事件之间挂起并一直这样做 直到流完成 ,因此在完成之前不会执行后面的代码。
我使用 `await 是因为我知道我有一个流会有有限的事件,我需要在做任何其他事情之前处理它们(基本上就像我正在处理一个期货列表)。
检查 https://www.dartlang.org/articles/language/beyond-async 以获得对 await for
的描述。
主要区别在于之后有代码。 listen
仅注册处理程序并继续执行。 await for
将保持执行直到流关闭。
因此,如果您在 main
的末尾添加一个 print('hello');
,您不应该在带有 await for
的输出中看到 hello (因为请求流永远不会关闭)。 Try the following code on dartpad 查看差异:
import 'dart:async';
main() async {
tenInts.listen((i) => print('int $i'));
//await for (final i in tenInts) {
// print('int $i');
//}
print('hello');
}
Stream<int> get tenInts async* {
for (int i = 1; i <= 10; i++) yield i;
}
一个更重要的区别是 await for
序列化流项目的消费,而 listen
将同时处理它们。
例如下面的代码:
import 'dart:async';
Future<void> process(int i) async {
print("start $i");
await new Future.delayed(const Duration(seconds: 1));
print("end $i");
}
main() async {
await for (final i in tenInts) {
await process(i);
}
tenInts.listen((i) async => await process(i));
print('hello');
}
Stream<int> get tenInts async* {
for (int i = 1; i <= 10; i++) yield i;
}
产量
start 1
end 1
start 2
end 2
start 3
end 3
start 4
end 4
start 5
end 5
start 6
end 6
start 7
end 7
start 8
end 8
start 9
end 9
start 10
end 10
hello
start 1
start 2
start 3
start 4
start 5
start 6
start 7
start 8
start 9
start 10
end 1
end 2
end 3
end 4
end 5
end 6
end 7
end 8
end 9
end 10
另一个区别是 listen()
returns 您的 StreamSubscription
对象,可以在以后的任何时间点用于 cancel/pause 订阅。您可以设置为每个数据事件或错误事件以及流关闭时调用的回调。
下面演示的是听流5秒后取消。
Stream<int> gen() async* {
for (int i = 1; i <= 10; i++) {
await Future.delayed(Duration(seconds: 1));
yield i;
}
print("done");
}
main() async {
Stream<int> stream = gen();
var subscription = stream.listen((item){
print(item);
});
await Future.delayed(Duration(seconds: 5));
subscription.cancel();
print("Exit");
}
Output:
1
2
3
4
Exit
正如罗布森所说:
await for serializes the consumption of the stream items while listen will process them concurrently.
我还想补充一点,如果使用 pause 和 resume 方法,虽然使用 listen 方法可以逐个处理流事件。 暂停方法应该在第一个 await 关键字之前调用。
StreamSubscription<int> subscription;
subscription = tenInts.listen((i) async {
subscription.pause();
await process(i);
subscription.resume();
});
Future<void> process(int i) async {
print("start $i");
await new Future.delayed(const Duration(seconds: 1));
print("end $i");
}