1

我想要

1.如果项目已经保存在数据库中,则将项目从可观察项目映射到另一个项目。

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

如何保持他们的订单结果?

4

1 回答 1

1

我回答自己来结束这个问题。

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

下面是 testMethod 的新实现。

异步地图版本:

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);
于 2019-06-01T05:29:52.850 回答