【问题标题】:How to map each item from observable to another one that comes from async function?如何将每个项目从可观察到另一个来自异步函数的项目?
【发布时间】:2019-05-31 17:01:11
【问题描述】:

我想要

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

2.否则,照原样使用。

并在结果中保持它们的顺序。

保存的项目有一些属性,比如标签,来自可观察的项目是'原始',它没有任何属性。

我写了这样的代码并运行 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

如何在结果中保持它们的顺序?

【问题讨论】:

  • 这样您就不会将您的项目与另一个 Observable“映射”,而是使用简单的 Future - 如此简单:Future findItemByKey(Item item) async { await Future.delayed(Duration(seconds: 1)); if (item.key == '1' || item.key == '4') item.tag = 'saved'; return item; } void testMethod() { Sample.getItems().asyncMap(findItemByKey).listen(print); } 就可以解决问题
  • 如果你真的想与另一个Observable“映射”使用flatMapconcatMapswitchMap
  • @pskink 我想用另一个Future 映射,所以这次我将使用asyncMap。谢谢!!

标签: flutter dart rxdart


【解决方案1】:

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

根据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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-02-17
    • 2015-07-14
    • 2018-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-22
    • 2016-04-15
    相关资源
    最近更新 更多