如何将每个项目从可观察到的映射到异步功能的另一个项目?

时间:2019-05-31 17:01:12

标签: flutter dart rxdart

我想

1.map项从可观察到另一个,如果它已经保存在数据库中。

2。否则,请按原样使用。

并保持其结果顺序。

已保存的项目具有一些属性,例如标记,而来自observable的项目为“原始”,则没有任何属性。

我写了这样的代码并运行testMethod。

    class Item {
      final String key;
      String tag;
      Item(this.key);
      @override
      String toString() {
        return ('key:$key,tag:$tag');
      }
    }

    class Sample {
    ///this will generate observable with 'raw' items.
    static Observable<Item> getItems() {
        return Observable.range(1, 5).map((index) => Item(index.toString()));
    }

    ///this will find saved item from repository if it exists.
    static Future<Item> findItemByKey(String key) async {
        //simulate database search
        await Future.delayed(Duration(seconds: 1));
        if (key == '1' || key == '4') {
            final item = Item(key)..tag = 'saved';
            return item;
        } else
            return null;
    }

    static void testMethod() {
        getItems().map((item) async {
            final savedItem = await findItemByKey(item.key);
            if (savedItem == null) {
                print('not saved:$item');
                return item;
            } else {
                print('saved:$savedItem');
                return savedItem;
            }
        }).listen((item) {});
    }

结果不理想。

预期:

saved:key:1,tag:saved
not saved:key:2,tag:null
not saved:key:3,tag:null
saved:key:4,tag:saved
not saved:key:5,tag:null

实际:

not saved:key:2,tag:null
not saved:key:3,tag:null
not saved:key:5,tag:null
saved:key:1,tag:saved
saved:key:4,tag:saved

如何保持结果顺序?

1 个答案:

答案 0 :(得分:0)

我回答自己以结束此问题。

根据pskink的comment,使用asyncMap或concatMap解决了我的问题。谢谢!

下面是testMethod的新实现。

asyncMap版本:

getItems().asyncMap((item) {
  final savedItem = findItemByKey(item.key);
  if (savedItem != null)
    return savedItem;
  else
    return Future.value(item);
}).listen(print);

concatMap版本:

getItems().concatMap((item) {
  final savedItem = findItemByKey(item.key);
  if (savedItem != null)
    return Observable.fromFuture(savedItem);
  else
    return Observable.just(item);
}).listen(print);