代码之家  ›  专栏  ›  技术社区  ›  knnhcn

RxJS使用两个参数订阅

  •  0
  • knnhcn  · 技术社区  · 8 年前

    我有两个观察值,我想合并,并在订阅中使用两个参数或只有一个。我试过了。ForkJoin。合并康卡特,但未能达到我所期待的行为。

    例子:

    obs1: Observable<int>;
    obs2: Observable<Boolean>;
    
    save(): Observable<any> {
       return obs1.concat(obs2);
    }
    

    service.save().subscribe((first, second) => {
        console.log(first); // int e.g. 1000
        console.log(second); // Boolean, e.g. true
    });
    

    或

    service.save().subscribe((first) => {
        console.log(first); // int e.g. 1000
    });
    

    希望有人能帮忙!

    编辑:

    obs1<int> 和 obs2<bool> 是两种不同的post请求: obs1<int> obs2<布尔>

    的价值 需要在请求完成后重新加载页面,并且 obs2<布尔> obs1<int> .

    obs2<布尔> 之前发射 obs1<int> obs1<int> 之前发射 ,页面将重新加载,消息可能不再显示。

    我这么说是因为对于给定的答案,无论值是在其他可观察值完成之前还是之后发出,都有不同的行为,这会影响用例。

    5 回复  |  直到 8 年前
        1
  •  3
  •   J. Pichardo    8 年前

    有几个操作员可以实现这一点:

    该算子将组合两个观察值发出的最新值,如大理石图所示:

    CombineLatest marble diagram

    obs1: Observable<int>;
    obs2: Observable<Boolean>;
    
    save(): Observable<any> {
       return combineLatest(obs1, obs2);
    }
    
    save().subscribe((val1, val2) => { 
       // logic
    });
    

    拉链

    Zip 操作员将等待两个观察值发出值,然后再发出一个值。

    Zip marble diagram

    obs1: Observable<int>;
    obs2: Observable<Boolean>;
    
    save(): Observable<any> {
       return zip(obs1, obs2);
    }
    
    save().subscribe((vals) => { 
       // Note Vals = [val1, val2]
       // Logic
    });
    

    或者,如果要对数组进行分解

    save().subscribe(([val1, val2]) => {
       // Logic
    });
    

    这个 WithLatestFrom 发出由可观察对象发出的最后值的组合,注意,此运算符跳过其他可观察对象中没有相应值的任何值。

    WithLatestFrom marble diagram

    save: obs1.pipe(withLatestFrom(secondSource))
    
    save().subscribe(([val1, val2]) => {
        // Logic
    });
    
        2
  •  3
  •   Amarnath    8 年前

    forkJoin 为此目的。平行地称呼他们,如果他们中的任何一个在场,那么做些什么。

    let numberSource = Rx.Observable.of(100);
    let booleanSource = Rx.Observable.of(true);
    
    Rx.Observable.forkJoin(
      numberSource,
      booleanSource
    ).subscribe( ([numberResp, booleanResp]) => {
      if (numberResp) {
        console.log(numberResp);
        // do something
      } else if (booleanResp) {
        console.log(booleanResp);
        // do something
      }
    });
    
        3
  •  1
  •   siva636    8 年前

    zip concat

    save(): Observable<any> {
       return zip(obs1, obs2);
    }
    

    service.save().subscribe((x) => {
        console.log(x[0]); // int e.g. 1000
        console.log(x[1]); // Boolean, e.g. true
    });
    
        4
  •  1
  •   bugs    8 年前

    要使用的确切运算符取决于您试图求解的具体细节。

    一个有效的选项是使用 combineLatest - Docs :

    obs1$: Observable<int>;
    obs2$: Observable<Boolean>;
    combined$ = combineLatest(obs1$, obs2$);
    
    combined$.subscribe(([obs1, obs2]) => {
      console.log(obs1);
      console.log(obs2);
    })
    
        5
  •  1
  •   bryan60    8 年前

    Concat通过流发出两个事件,一个在另一个完成后,这不是你想要的。

    您想要的是同一个流事件中两个项的值。forkJoin、zip和CombineTest都可以做到这一点,但你们会被绊倒的是,它们都会发出一个值数组,而你们在subscribe中并没有正确访问这些值。

    每次压缩在一起的所有项目按顺序发射时,zip发射,因此如果可观察1发射1,2,3,可观察2发射4,5;压缩空气排放量将为[1,4]、[2,5]。

    CombineTest每次都会发射,所以你会得到[1,4]、[2,4]、[2,5]、[3,5](取决于确切的发射顺序)。

    我个人会这样做:

    obs1: Observable<int>;
    obs2: Observable<Boolean>;
    
    save(): Observable<any> {
       return forkJoin(obs1, obs2);
    }
    
    service.save().subscribe(([first, second]) => {
        console.log(first); // int e.g. 1000
        console.log(second); // Boolean, e.g. true
    });
    

    Typescript提供了这样的语法来访问一个已知长度的数组中的项,但无法在subscribe success函数中真正创建多个参数,因为它的接口只接受一个参数。

    推荐文章