如何将每个项目从 observable 映射到另一个来自异步函数的项目?
How to map each item from observable to another one that comes from async function?
我要
1.map 项目从可观察到另一个如果它已经保存在数据库中。
2.otherwise,照原样使用
并在结果中保留他们的顺序。
保存的项目有一些 属性 类似的标签,而来自 observable 的项目是 '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
如何保持他们在结果中的顺序?
我自己回答来结束这个问题。
根据 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);
我要
1.map 项目从可观察到另一个如果它已经保存在数据库中。
2.otherwise,照原样使用
并在结果中保留他们的顺序。
保存的项目有一些 属性 类似的标签,而来自 observable 的项目是 '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
如何保持他们在结果中的顺序?
我自己回答来结束这个问题。
根据 pskink 的
下面是 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);