Как отобразить каждый элемент из наблюдаемого в другой, который получен из асинхронной функции? - PullRequest
0 голосов
/ 31 мая 2019

Я хочу

1.map элемент из наблюдаемого в другой, если он уже сохранен в базе данных.

2.в противном случае используйте его как есть.

и сохраняйте их порядок в результате.

Сохраненный элемент имеет какое-либо свойство, такое как tag, а элемент из наблюдаемого является 'raw', у него нет никакого свойства.

Я написал такой код и запустил 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 голосов
/ 01 июня 2019

Я отвечаю себе, чтобы закрыть этот вопрос.

Согласно комментарию от pskink, используйте 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);
...