关于完成者的一些解释

时间:2014-11-09 20:42:09

标签: dart dart-mirrors

大家好

我有一个班'示例'需要做一些计算。我调用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。所以我不明白为什么它已经完成了。

如果有人可以解释为什么这样的代码不正确,并且可能会给我一些有趣的链接,那就太棒了

干杯!

2 个答案:

答案 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;
  }
}