3

次のコードを検討してください。

import 'dart:async';

abstract class ClassAbstract
{
   Completer<String> _onEvent1;
   Completer<int> _onEvent2;

   ClassAbstract()
   {
     _onEvent1 = new Completer<String>();
     _onEvent2 = new Completer<int>();
   }

   Future get Event1
   {
      return _onEvent1.future; 
   }

   Future get Event2
   {
      return _onEvent2.future;
   }
}

class NormalClass extends ClassAbstract
{
   NormalClass(): super()
   {
     _onEvent1.complete("Event1 rise");
     for (int iCounter = 0; iCounter < 100; iCounter++)
     {
       _onEvent2.complete(iCounter);
     }
  }
}


void main() {

  NormalClass normalClass = new NormalClass();

  normalClass.Event1.then( (val) { print("Event1 rised"); } );
  normalClass.Event2.then( (val) { print("Event2 rised: $val"); } );

  print("Application close");
}

ご覧のとおり、1 つabstractのクラスに 2 つのクラスがFutures定義され、それらの 2 の getter を持つ非常に単純なコードですFutures。このクラスを実装し、 .NET イベント システムをシミュレートabstractするために を呼び出す別のクラス。Features

問題は、このコードを実行するたびにfor(int iCounter....) 、 error: に沿ったエラーで失敗することですFuture already complete

completeFuture は一度しかできないということですか?

4

3 に答える 3

3

それは正しいです。Future は、使い捨ての非同期呼び出し用に設計されています。基本的に、未来は 1 つの値しか提供できません。複数の値を提供したい場合は、Streamを利用する必要があります。StreamControllerを使用すると、サブスクライブできる複数の値を簡単に追加できます。

したがって、サンプルは次のようになります。

import 'dart:async';

abstract class ClassAbstract
{
   StreamController<String> _onEvent1;
   StreamController<int> _onEvent2;

   ClassAbstract()
   {
     _onEvent1 = new StreamController<String>();
     _onEvent2 = new StreamContorller<int>();
   }

   Future get Event1
   {
      return _onEvent1.stream; 
   }

   Future get Event2
   {
      return _onEvent2.stream;
   }
}

class NormalClass extends ClassAbstract
{
   NormalClass(): super()
   {
     _onEvent1.add("Event1 rise");
     for (int iCounter = 0; iCounter < 100; iCounter++)
     {
       _onEvent2.add(iCounter);
     }
  }
}

そして、次のように呼ぶことができます:

main() {
  var sum = 0;
  var thing = new NormalClass();
  thing.Event1.listen((myStr) => print(myStr));
  thing.Event2.listen((val) { 
    sum += val;
  });
}
于 2013-04-04T12:32:51.667 に答える
2

それでおしまい。複数の値をトリガーする場合は、StreamおよびStreamControllerを処理する必要があります。詳しくは、新しい Streams API の紹介を参照してください。

于 2013-04-04T12:21:57.780 に答える
1

はい、Completer は Future を 1 回しか完了できません。これが最も明白に思えます。Future は基本的に、(「1」を読み取る) 非同期操作のトークンです。成功するか失敗するかのどちらかです。

あなたのケースで探しているのは、イベントをディスパッチするソースと、ソースでイベントをリッスンするリスナーがあるオブザーバー パターンです。このシナリオでは、ソースは同じイベントを複数回ディスパッチできます。

編集: Streams API にいくつかのリンクを追加しようとしていましたが、Alexandre が私を打ち負かしました。詳細については、 API ドキュメントを確認してください。

于 2013-04-04T12:21:24.067 に答える