Return 在 Dart 中按照队列中的执行顺序同步异步调用 Futures
Return synchronously called Futures asynchronously in order of execution in queue in Dart
void main() async {
Future<void> asyncFunction(time, value) async {
return await Future.delayed(Duration(seconds: time), () => print(value));
}
print('1');
asyncFunction(2, "A");
asyncFunction(1, "B");
asyncFunction(0, "C");
print('2');
}
根据上面的代码,我试图让代码打印为:
1
2
A
B
C
我想同步执行所有函数并将 asyncFunctions (Futures) 发送到某种队列,然后按接收到的顺序执行这些函数。每个函数必须等待前一个函数完成它的 Future,然后它自己执行。
我一直在尝试使用流,但没有做对。
这个有用吗?
void main() async {
Future<void> asyncFunction(time, value) async {
return await Future.delayed(Duration(seconds: time), () => print(value));
}
print('1');
print('2');
await asyncFunction(2, "A");
await asyncFunction(1, "B");
await asyncFunction(0, "C");
}
好的,我想出了一些基本的东西:
import 'dart:async';
import 'dart:collection';
import 'dart:math';
var streamController = StreamController<String>();
Queue queue = Queue();
bool busy = false;
Future<void> asyncFunction(value) async {
await Future.delayed(Duration(seconds: Random().nextInt(4)));
return print(value);
}
void main() async {
streamController.stream.listen((letter) async {
queue.add(letter);
if (!busy) {
busy = true;
while (busy) {
await asyncFunction(queue.first);
queue.removeFirst();
if (queue.isEmpty) {
busy = false;
}
}
}
});
print("1");
streamController.add("A");
streamController.add("B");
streamController.add("C");
streamController.add("D");
print("2");
streamController.add("E");
streamController.add("F");
streamController.add("G");
streamController.add("H");
print("3");
print("-");
}
给出期望的结果:
1
2
3
-
A
B
C
D
E
F
G
H
无法使 Future.delayed(2, ...)
在 Future.delayed(1, ...)
之前完成。时间不是这样运作的。相反,您可以做的是依赖 return 值而不是副作用,然后您可以构建 Future
的 List
并使用 Future.wait
来收集结果并按原始顺序打印它们:
void main() async {
Future<dynamic> asyncFunction(time, value) async {
await Future.delayed(Duration(seconds: time));
return value;
}
var futures = <Future<dynamic>>[];
print('1');
futures.add(asyncFunction(2, "A"));
futures.add(asyncFunction(1, "B"));
futures.add(asyncFunction(0, "C"));
print('2');
var results = await Future.wait(futures);
for (var result in results) {
print(result);
}
}
上述方法的好处是允许多个异步操作可能 运行 并行。
或者,您可以延迟构建 Future.delayed(...)
对象,这样每个对象都不会创建,直到前一个对象完成:
void main() async {
Future<void> asyncFunction(time, value) async {
await Future.delayed(Duration(seconds: time), () => print(value));
}
var queue = <Future<void> Function()>[];
print('1');
queue.add(() => asyncFunction(2, "A"));
queue.add(() => asyncFunction(1, "B"));
queue.add(() => asyncFunction(0, "C"));
print('2');
for (var thunk in queue) {
await thunk();
}
}
如果你想要一个异步任务队列,其中每个新添加的任务都会延迟到前一个任务完成,你可以自己写一个。
class AsyncQueue<T> {
Future<T?> _current = Future.value(null);
Future<T> add(FutureOr<T> Function() task) {
FutureOr<T> wrapper(void _) => task();
return _current = _current.then(wrapper, onError: wrapper);
}
}
您可以将其用作:
Future<void> asyncFunction(time, value) async {
await Future.delayed(Duration(seconds: time), () => print(value));
}
...
var queue = AsyncQueue<void>();
print("1");
var f1 = queue.add(() => asyncFunction(2, "A"));
var f2 = queue.add(() => asyncFunction(1, "B"));
var f3 = queue.add(() => asyncFunction(0, "C"));
print("2");
await f3;
void main() async {
Future<void> asyncFunction(time, value) async {
return await Future.delayed(Duration(seconds: time), () => print(value));
}
print('1');
asyncFunction(2, "A");
asyncFunction(1, "B");
asyncFunction(0, "C");
print('2');
}
根据上面的代码,我试图让代码打印为:
1
2
A
B
C
我想同步执行所有函数并将 asyncFunctions (Futures) 发送到某种队列,然后按接收到的顺序执行这些函数。每个函数必须等待前一个函数完成它的 Future,然后它自己执行。
我一直在尝试使用流,但没有做对。
这个有用吗?
void main() async {
Future<void> asyncFunction(time, value) async {
return await Future.delayed(Duration(seconds: time), () => print(value));
}
print('1');
print('2');
await asyncFunction(2, "A");
await asyncFunction(1, "B");
await asyncFunction(0, "C");
}
好的,我想出了一些基本的东西:
import 'dart:async';
import 'dart:collection';
import 'dart:math';
var streamController = StreamController<String>();
Queue queue = Queue();
bool busy = false;
Future<void> asyncFunction(value) async {
await Future.delayed(Duration(seconds: Random().nextInt(4)));
return print(value);
}
void main() async {
streamController.stream.listen((letter) async {
queue.add(letter);
if (!busy) {
busy = true;
while (busy) {
await asyncFunction(queue.first);
queue.removeFirst();
if (queue.isEmpty) {
busy = false;
}
}
}
});
print("1");
streamController.add("A");
streamController.add("B");
streamController.add("C");
streamController.add("D");
print("2");
streamController.add("E");
streamController.add("F");
streamController.add("G");
streamController.add("H");
print("3");
print("-");
}
给出期望的结果:
1
2
3
-
A
B
C
D
E
F
G
H
无法使 Future.delayed(2, ...)
在 Future.delayed(1, ...)
之前完成。时间不是这样运作的。相反,您可以做的是依赖 return 值而不是副作用,然后您可以构建 Future
的 List
并使用 Future.wait
来收集结果并按原始顺序打印它们:
void main() async {
Future<dynamic> asyncFunction(time, value) async {
await Future.delayed(Duration(seconds: time));
return value;
}
var futures = <Future<dynamic>>[];
print('1');
futures.add(asyncFunction(2, "A"));
futures.add(asyncFunction(1, "B"));
futures.add(asyncFunction(0, "C"));
print('2');
var results = await Future.wait(futures);
for (var result in results) {
print(result);
}
}
上述方法的好处是允许多个异步操作可能 运行 并行。
或者,您可以延迟构建 Future.delayed(...)
对象,这样每个对象都不会创建,直到前一个对象完成:
void main() async {
Future<void> asyncFunction(time, value) async {
await Future.delayed(Duration(seconds: time), () => print(value));
}
var queue = <Future<void> Function()>[];
print('1');
queue.add(() => asyncFunction(2, "A"));
queue.add(() => asyncFunction(1, "B"));
queue.add(() => asyncFunction(0, "C"));
print('2');
for (var thunk in queue) {
await thunk();
}
}
如果你想要一个异步任务队列,其中每个新添加的任务都会延迟到前一个任务完成,你可以自己写一个。
class AsyncQueue<T> {
Future<T?> _current = Future.value(null);
Future<T> add(FutureOr<T> Function() task) {
FutureOr<T> wrapper(void _) => task();
return _current = _current.then(wrapper, onError: wrapper);
}
}
您可以将其用作:
Future<void> asyncFunction(time, value) async {
await Future.delayed(Duration(seconds: time), () => print(value));
}
...
var queue = AsyncQueue<void>();
print("1");
var f1 = queue.add(() => asyncFunction(2, "A"));
var f2 = queue.add(() => asyncFunction(1, "B"));
var f3 = queue.add(() => asyncFunction(0, "C"));
print("2");
await f3;