大家好
我有一个班'示例'需要做一些计算。我调用start()调用_next()。在计算过程中_next()调用自己几次,但在我的例子中,我使用Timer模拟它。这是我的代码
import "dart:async";
main() {
Example ex = new Example();
for (var i = 0 ; i < 3 ; i++) {
ex.start().then((nbr) {
print(nbr);
});
}
}
class Example {
/// for _next
Completer _insideCompleter;
/// from start() to outside
Completer _outsideCompleter;
Example();
/// start is just a better public api than next when we start the exercise
Future<int> start() {
_insideCompleter = new Completer();
_outsideCompleter = new Completer();
_next().then((int value) {
print("value: $value");
_outsideCompleter.complete(value);
}).catchError((message) {
print("information: $message");
});
return _outsideCompleter.future;
}
/// _next handle the flow with the status
Future<int> _next() {
new Timer(new Duration(seconds: 6), () {
_insideCompleter.complete(15);
});
return _insideCompleter.future;
}
}
它结束于:糟糕的状态:未来已经完成。但正如你在start()中看到的那样。使用new重新创建Completer。所以我不明白为什么它已经完成了。
如果有人可以解释为什么这样的代码不正确,并且可能会给我一些有趣的链接,那就太棒了
干杯!
答案 0 :(得分:1)
我不完全确定您对代码的意图是什么,但我认为您应该
Example ex = new Example();
for (var i = 0 ; i < 3 ; i++) { // create a new Example() for each iteration here
ex.start().then((nbr) { // or ensure that the next iteration is not executed
print(nbr); // before the previous is completed.
});
}
在第一次调用完成之前,使用此代码ex.start()
被调用3次。
答案 1 :(得分:1)
这里的主要问题是关于在回调函数中调用的完成者
_next().then((int value) {
print("value: $value");
_outsideCompleter.complete(value); // this line
})
和
new Timer(new Duration(seconds: 6), () {
_insideCompleter.complete(15); // this line
});
因为在你的循环之后调用了这个2函数并且 你的完成符是属性 ,所以所有的回调都将使用最新的_outsideCompleter和_insideCompleter创建。
因此,在其中一个回调“消耗”你的完成者之后,其他人将创建“坏状态:未来已经完成”的例外
这是一个有效的版本
import "dart:async";
main() {
Example ex = new Example();
for (var i = 0 ; i < 3 ; i++) {
ex.start().then((nbr) {
print(nbr);
});
}
}
class Example {
Example();
/// start is just a better public api than next when we start the exercise
Future<int> start() {
var outsideCompleter = new Completer(); // create localy each times
_next().then((int value) {
print("value: $value");
outsideCompleter.complete(value);
}).catchError((message) {
print("information: $message");
});
return outsideCompleter.future;
}
/// _next handle the flow with the status
Future<int> _next() {
var insideCompleter = new Completer(); // create localy each times
new Timer(new Duration(seconds: 6), () {
insideCompleter.complete(15);
});
return insideCompleter.future;
}
}