Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/30.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular RxJS-如果满足某些条件,则跳过函数_Angular_Typescript_Rxjs - Fatal编程技术网

Angular RxJS-如果满足某些条件,则跳过函数

Angular RxJS-如果满足某些条件,则跳过函数,angular,typescript,rxjs,Angular,Typescript,Rxjs,在我正在开发的Angular Web应用程序中,我需要使用Observables做很多事情。 通常,Observables用于异步事件序列,但是,对我来说,通常只有一个结果(来自http请求)。 我经常需要进行一些复杂的映射,以便从http请求中获得所需的结果。但是,仅当满足某些条件时才需要此映射,否则我可以跳过整个映射部分并返回默认值。 例如: 我想得到特定商品在给定城市的销售总额 要获得结果,需要执行以下步骤: 获取所有客户s,他们居住在给定的城市 city.getClients():可观察

在我正在开发的Angular Web应用程序中,我需要使用
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
    操作员之前执行一些网络请求,但该请求失败,该怎么办?