dart 中的 Future / Completer 行为不是 运行 异步
Future / Completer behavior in dart not running asynchronously
我只是想了解期货的行为。这是一个示例代码:
import'dart:async';
main() {
Future short = shortWait();
Future medium = mediumWait();
Future long = longWait();
long.then((String e)=>print(e));
medium.then((String e)=> print(e));
short.then((String e)=> print(e));
}
Future<String> longWait() {
Completer c = new Completer<String>();
for (int i=0; i<100000000; i++); // creating long latency
c.complete("long");
return c.future;
}
Future<String> mediumWait() {
Completer c = new Completer<String>();
for (int i=0; i<10000; i++); // creating medium length latency
c.complete("medium");
return c.future;
}
Future<String> shortWait() {
Completer c = new Completer<String>();
c.complete("short"); // no latency
return c.future;
}
// short
// medium
// long
我注意到了一些事情。首先,代码似乎是同步的,最长延迟函数 longWait() 正在阻塞。直到一切都可用时才会显示输出,然后一次显示所有内容。我认为它应该首先显示可用的内容,然后在 Futures 完成时显示。
其次,显示顺序似乎反映了 Future short/medium/long = shortWait/mediumWait/longWait() 的显示顺序。即改变这些行的顺序,输出的顺序也会相应改变。每种方法的延迟时间有多长都没有关系,short/medium/long.then((e) => print(e)).
的显示顺序也没有任何区别
我希望代码 1) 在数据可用时显示输出,以及 2) 输出顺序应反映函数的延迟。除了了解 Futures 的基本概念之外,我实际上并没有尝试做任何事情。
Future<String> longWait() {
Completer c = new Completer<String>();
for (int i = 0; i < 100000000; i++); // creating long latency
c.complete("long");
return c.future;
}
这不是异步处理。只有在 for 循环完成后,您才返回未来。这使得这个函数同步。
要使其异步,请尝试以下操作:
Future<String> longWait() {
Completer c = new Completer<String>();
new Future.delayed(new Duration(seconds: 4), () {
c.complete('long');
});
return c.future;
}
Future<String> mediumWait() {
Completer c = new Completer<String>();
new Future.delayed(new Duration(seconds: 2), () {
c.complete('medium');
});
return c.future;
}
Future<String> shortWait() {
Completer c = new Completer<String>();
new Future.delayed(new Duration(seconds: 0), () {
c.complete('short');
});
return c.future;
}
理想情况下,您可以完全避免使用 Completer
,因为 Future.delayed
returns 一个未来。
Future<String> longWait() {
return new Future.delayed(new Duration(seconds: 10), ()=>'long');
}
Future<String> mediumWait() {
return new Future.delayed(new Duration(seconds: 5), ()=>'medium');
}
Future<String> shortWait() {
return new Future.delayed(new Duration(seconds: 0), ()=>'short');
}
请记住,Dart 中的异步 并不意味着并行。
您在示例中所做的实质是将五个任务放入队列中:
- 数到 100000000
- 打印'long'
- 数到 10000
- 打印'medium'
- 打印'short'
所以他们按照那个顺序执行。
在 Dart 中,异步 意味着代码在等待某事发生时不必阻塞。这通常是核心库提供的功能,例如从文件中获取数据或通过网络进行交互 - 由操作系统或浏览器执行的任务。
一种思考方式是 Dart 程序可以执行 'in parallel' 由操作系统或浏览器完成的事情,而不是它本身。
Dart 还可以通过等待计时器触发来执行代码 'in parallel'。例如:
import 'dart:async';
main() {
// Long latency
(new Future.delayed(new Duration(seconds: 5)).then((_) => print('long')));
// Medium latency
(new Future.delayed(new Duration(seconds: 2)).then((_) => print('medium')));
// Short latency
(new Future.delayed(new Duration(seconds: 1)).then((_) => print('short')));
print('go');
}
打印:
go
short
medium
long
我只是想了解期货的行为。这是一个示例代码:
import'dart:async';
main() {
Future short = shortWait();
Future medium = mediumWait();
Future long = longWait();
long.then((String e)=>print(e));
medium.then((String e)=> print(e));
short.then((String e)=> print(e));
}
Future<String> longWait() {
Completer c = new Completer<String>();
for (int i=0; i<100000000; i++); // creating long latency
c.complete("long");
return c.future;
}
Future<String> mediumWait() {
Completer c = new Completer<String>();
for (int i=0; i<10000; i++); // creating medium length latency
c.complete("medium");
return c.future;
}
Future<String> shortWait() {
Completer c = new Completer<String>();
c.complete("short"); // no latency
return c.future;
}
// short
// medium
// long
我注意到了一些事情。首先,代码似乎是同步的,最长延迟函数 longWait() 正在阻塞。直到一切都可用时才会显示输出,然后一次显示所有内容。我认为它应该首先显示可用的内容,然后在 Futures 完成时显示。
其次,显示顺序似乎反映了 Future short/medium/long = shortWait/mediumWait/longWait() 的显示顺序。即改变这些行的顺序,输出的顺序也会相应改变。每种方法的延迟时间有多长都没有关系,short/medium/long.then((e) => print(e)).
的显示顺序也没有任何区别我希望代码 1) 在数据可用时显示输出,以及 2) 输出顺序应反映函数的延迟。除了了解 Futures 的基本概念之外,我实际上并没有尝试做任何事情。
Future<String> longWait() {
Completer c = new Completer<String>();
for (int i = 0; i < 100000000; i++); // creating long latency
c.complete("long");
return c.future;
}
这不是异步处理。只有在 for 循环完成后,您才返回未来。这使得这个函数同步。
要使其异步,请尝试以下操作:
Future<String> longWait() {
Completer c = new Completer<String>();
new Future.delayed(new Duration(seconds: 4), () {
c.complete('long');
});
return c.future;
}
Future<String> mediumWait() {
Completer c = new Completer<String>();
new Future.delayed(new Duration(seconds: 2), () {
c.complete('medium');
});
return c.future;
}
Future<String> shortWait() {
Completer c = new Completer<String>();
new Future.delayed(new Duration(seconds: 0), () {
c.complete('short');
});
return c.future;
}
理想情况下,您可以完全避免使用 Completer
,因为 Future.delayed
returns 一个未来。
Future<String> longWait() {
return new Future.delayed(new Duration(seconds: 10), ()=>'long');
}
Future<String> mediumWait() {
return new Future.delayed(new Duration(seconds: 5), ()=>'medium');
}
Future<String> shortWait() {
return new Future.delayed(new Duration(seconds: 0), ()=>'short');
}
请记住,Dart 中的异步 并不意味着并行。
您在示例中所做的实质是将五个任务放入队列中:
- 数到 100000000
- 打印'long'
- 数到 10000
- 打印'medium'
- 打印'short'
所以他们按照那个顺序执行。
在 Dart 中,异步 意味着代码在等待某事发生时不必阻塞。这通常是核心库提供的功能,例如从文件中获取数据或通过网络进行交互 - 由操作系统或浏览器执行的任务。
一种思考方式是 Dart 程序可以执行 'in parallel' 由操作系统或浏览器完成的事情,而不是它本身。
Dart 还可以通过等待计时器触发来执行代码 'in parallel'。例如:
import 'dart:async';
main() {
// Long latency
(new Future.delayed(new Duration(seconds: 5)).then((_) => print('long')));
// Medium latency
(new Future.delayed(new Duration(seconds: 2)).then((_) => print('medium')));
// Short latency
(new Future.delayed(new Duration(seconds: 1)).then((_) => print('short')));
print('go');
}
打印:
go
short
medium
long