Angular RxJS-如果满足某些条件,则跳过函数
在我正在开发的Angular Web应用程序中,我需要使用Angular RxJS-如果满足某些条件,则跳过函数,angular,typescript,rxjs,Angular,Typescript,Rxjs,在我正在开发的Angular Web应用程序中,我需要使用Observables做很多事情。 通常,Observables用于异步事件序列,但是,对我来说,通常只有一个结果(来自http请求)。 我经常需要进行一些复杂的映射,以便从http请求中获得所需的结果。但是,仅当满足某些条件时才需要此映射,否则我可以跳过整个映射部分并返回默认值。 例如: 我想得到特定商品在给定城市的销售总额 要获得结果,需要执行以下步骤: 获取所有客户s,他们居住在给定的城市 city.getClients():可观察
Observable
s做很多事情。通常,
Observable
s用于异步事件序列,但是,对我来说,通常只有一个结果(来自http请求)。我经常需要进行一些复杂的映射,以便从http请求中获得所需的结果。但是,仅当满足某些条件时才需要此映射,否则我可以跳过整个映射部分并返回默认值。
例如:
我想得到特定
商品
在给定城市
的销售总额要获得结果,需要执行以下步骤:
客户
s,他们居住在给定的城市
city.getClients():
可观察
(http获取
->可观察
)
客户
确定给定商品
的销售额(
flatMap
->可观察的
)客户的给定商品的总销售额。
(地图
->可观察
)
(
地图
->可观察
)客户住在该城市。
在这种情况下,可以跳过步骤2-4,并使用值0
调用onNext
-回调
注意,这只是一个简单的例子,用来解释我想做什么。真正的用例需要更多的步骤,我需要做一个
if (meetsCondition(x))
return map(x);
else
return defaultValue;
每一步
过滤器
-功能几乎就是我想要的。但是,它不会为过滤后的值调用onNext
有没有办法实现我所追求的目标
编辑:
我将尝试为问题添加更多细节:
我的应用程序中有很多延迟加载的数据。因此,如果您请求一个城市
,它将不会加载相关的客户端
,除非您通过调用getClients
请求它们
因此,大多数的getter
s返回数据的可观察的
,而不是数据本身
现在我经常需要通过组合不同来源的值来计算东西(client
,article
等)。
通常,这种计算可以在中间停止,因为没有确定有效的结果。
如果值为空,但如果筛选列表包含多个条目,则可能会出现这种情况
因此,对我来说,完美的解决方案是,如果我能做这样的事情:
client.getOrders()
.skipIf(value => !meetsCondition(value), defaultValue)
.map(value => mapValue(value)) // Probably not called
.map(value => mapValueAgain(value)) // Probably not called
.subscribe(value => {
if (value == defaultValue)
console.log("Skip");
else
console.log(value)
});
我对你的案子的解释如下。对吧?
function getClients(city:string) {
return Observable.of(city == 'Seoul' ? ['c1', 'c2'] : []).delay(100);
}
function getSales(client:string, article:string) {
let sales:any = {
'c1': {
'item1': 10,
'item2': 20
},
'c2': {
'item1': 30,
'item2': 40
}
};
return Observable.of(sales[client][article]).delay(100);
}
let city = 'Seoul';
let article = 'item2';
getClients(city)
.mergeMap(clients => {
console.log('>> mergeMap');
let salesObs = clients.map<Observable<number>>(client => getSales(client, article));
return Observable.merge(salesObs).mergeAll();
})
.reduce((sum, sales) => {
console.log('>> reduce');
return sum + sales;
}, 0)
.subscribe(value => console.log(`sum = ${value}`));
函数getClients(城市:字符串){
可观测的返回。of(城市==‘首尔’?[‘c1’、‘c2’]:[])。延迟(100);
}
函数getSales(客户机:字符串,文章:字符串){
让销售:任何={
“c1”:{
“项目1”:10,
“项目2”:20
},
“c2”:{
“项目1”:30,
“项目2”:40
}
};
可观察到的(销售[客户][物品])延迟回报(100);
}
让城市=首尔;
让article='item2';
GetClient(城市)
.mergeMap(客户端=>{
log('>>mergeMap');
让salesObs=clients.map(client=>getSales(client,article));
返回Observable.merge(salesObs.mergeAll();
})
.减少((总和,销售额)=>{
log('>>reduce');
退货金额+销售额;
}, 0)
.subscribe(value=>console.log(`sum=${value}`));
在这种情况下,虽然客户端是空的,但没有问题。将“城市”更改为其他值,然后重试
我添加了一些代码,使用“map”和“catch”在一般条件下工作。
如果它满足某些跳过条件,则不会执行“mergeMap”和“reduce”
getClients(city)
.map(clients => {
// some skip condition
if (clients.length == 0)
throw 0 /* default value */;
return clients;
})
.mergeMap(clients => {
console.log('>> mergeMap');
let salesObs = clients.map<Observable<number>>(client => getSales(client, article));
return Observable.merge(salesObs).mergeAll();
})
.reduce((sum, sales) => {
console.log('>> reduce');
return sum + sales;
}, 0)
.catch((err, caught) => {
console.log('>> catch');
// default value
return Observable.of(err);
})
.subscribe(value => console.log(`sum = ${value}`));
getClients(城市)
.map(客户端=>{
//某些跳跃条件
if(clients.length==0)
抛出0/*默认值*/;
返回客户;
})
.mergeMap(客户端=>{
log('>>mergeMap');
让salesObs=clients.map(client=>getSales(client,article));
返回Observable.merge(salesObs.mergeAll();
})
.减少((总和,销售额)=>{
log('>>reduce');
退货金额+销售额;
}, 0)
.catch((错误,捕获)=>{
log('>>catch');
//默认值
可观察的回报率(误差);
})
.subscribe(value=>console.log(`sum=${value}`));
您是否查看了可观察到的接收信号。如果
?它可能满足您的需要。但是我需要在每一步都使用if
,对吗?另外,如果我需要在满足条件的情况下执行flatMap
(或任何其他RXJS操作符),我将无法正确执行该操作?您是否尝试将回调作为参数赋给getClients
方法?通过这种方式,如果结果为空,则可以调用emptyCallback
,如果不是,则可以调用所需的任何内容。问题是,此“筛选器”并不总是适用于空值。有时我需要“过滤”,如果确定的列表中没有一个条目。另外,getClients
是一个通用的getter方法,返回一个延迟加载的客户端列表,所以我不想添加一个参数?我可以catch
在给定的点上捕获它,然后执行将继续?catch
返回可观察的not值。所以你可以执行你想要的任务。非常感谢,我会尽力让你知道结果!我只是试了一下,似乎效果不错。现在,每当我想跳过某些执行时,我可以添加一个抛出
,每当我想让跳过的值重新输入序列时,我可以添加一个捕获
。谢谢!这种方法不会放弃错误处理吗?如果出现实际错误,例如您需要在catch
操作员之前执行一些网络请求,但该请求失败,该怎么办?