2016-06-24 20 views
2

非同期マッピング関数を使用してIterableをマップできますか?おそらく、バグで、このコードは1から5秒後にintではなく、_Futureのリストを即時に出力しますか?ダーツの非同期iterableマッピング

import 'dart:async'; 

Future<int> foo(int i) { 
    var c = new Completer(); 
    new Timer(new Duration(seconds: 1),() => c.complete(i)); 
    return c.future; 
} 

main() { 
    var list = [1,2,3,4,5]; 
    var mappedList = list.map((i) async => await foo(i)); 
    print(mappedList); 
} 

答えて

1

(i) async => await foo(i)は未来を返します。作成されたすべての先物が完了するまで、Future.wait(mappedList)を使用して待機することができます。いくつかのタイプを追加する

1

は何が起こっているかを説明します:

main() async { 
    var list = [1,2,3,4,5]; 
    Iterable<Future<int>> mappedList = list.map((i) async => await foo(i)); 
    print(mappedList); // you print an Iterable of Future 

    // to get the list of int you have to do the following 
    Future<List<int>> futureList = Future.wait(mappedList); 
    List<int> result = await futureList; 
    print(result); 
} 
2

あなたの誤解は、非同期機能がFuture、ない値を返すということです。 awaitは、asyncをsyncに変換しません。

var mappedList = list.map(
    (i) async => await foo(i) // Returns a Future, not an int 
); 

(i) async => await foo(i)から返された先物です。

これらの先物は、先物のチェーンが完了した時点で完了します。タイマーが起動すると、foo()が完了し、次にawait foo(i)にマッピングされます。 https://dartpad.dartlang.org/151949be67c0cdc0c54742113c98b291

いくつかの点に注意する:Dartpadオン

main() async { 
    List<int> list = [1,2,3,4,5]; 
    Iterable<Future<int>> mapped; 

    // Prints ints 1 second apart 
    mapped = list.map((i) => foo(i)); 
    for(Future<int> f in mapped) { 
    print(await f); 
    } 

    // Prints ints all at once, after 1 second wait 
    mapped = list.map((i) => foo(i)); 
    for(Future<int> f in mapped) { 
    f.then(print); 
    } 
} 

は、と比較し

List.map()を返し怠惰Iterable(ないList)マッピング関数ISN」の意味Iterableが繰り返されるまで呼び出されません。

印刷前に完了する各Futureための第1のループ待機しIterable内の次の項目に移動する、次の項目(従ってfoo())のマッピング関数は、値があるので、それぞれの値を印刷後と呼ばれています1秒間隔で印刷される。

2番目のループは、Futureが完了するたびに実行する印刷機能を設定してすぐにIterableを反復します。関数foo()の5つのインスタンスが一度に呼び出されます。すべて約1秒後に戻り、5つの値がすべて出力されます。

関連する問題