2013-04-04 69 views
2

請考慮下面的代碼:未來/完成者只能被調用一次?

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 Futures。另一個類實現此類abstract類並調用Features來模擬.NET事件系統。

問題是,每當我運行此代碼時,它會失敗,出現錯誤for(int iCounter....)錯誤:Future already complete

這是否意味着我可以complete未來只有一次?

回答

2

就是這樣。如果你想觸發幾個值,你必須處理StreamStreamController。有關更多信息,請參閱Introducing new Streams API

+0

是的..我已經找到了這個:https://code.google.com/p/dart/issues/detail?id=1873和這個:http://pub.dartlang.org/packages/event_stream 順便說一句:事件的可觀察執行是*驚人的* – Jasper 2013-04-04 12:29:21

1

是的,一個Completer只能完成一次Future,這對我來說似乎是最明顯的。未來基本上是一個(讀'一')異步操作的標誌。它會成功或失敗。

你在你的情況下尋找的是一個觀察者模式,其中有一個源調度事件和偵聽器來偵聽源上的事件。在這種情況下,源可以多次分派相同的事件。

編輯:我正要添加一些鏈接到Streams API,但亞歷山大打我。查看API docs瞭解更多信息。

+0

令牌?它是2階段回調。一旦你定義它:completer.future,一旦你執行它:completer.complete().....這就是它我猜。太糟糕了..我認爲它的概念與'事件'非常相似,但它不是 - 它只是一個回調..... – Jasper 2013-04-04 12:27:15

+0

我稱它爲一個令牌,關於接收未來的客戶端並在其上註冊回調處理結果和錯誤。類似於Flex框架中的AsyncToken類:http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/rpc/AsyncToken.html – 2013-04-04 12:30:10

+0

對不起。不知道Flex ... I有C#背景 – Jasper 2013-04-04 12:31:33

3

這是正確的。期貨被設計用於一次性異步呼叫。基本上,未來只能提供一個價值。如果你想提供多個值,那麼你會想要使用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; 
    }); 
} 
+0

酷解決方案! – Jasper 2013-04-04 12:38:59