Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/471.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
Javascript RxJS使用两个参数订阅_Javascript_Angular_Typescript_Rxjs - Fatal编程技术网

Javascript RxJS使用两个参数订阅

Javascript RxJS使用两个参数订阅,javascript,angular,typescript,rxjs,Javascript,Angular,Typescript,Rxjs,我有两个要合并的观测值,它们要么同时使用两个参数,要么只使用一个参数。我尝试了.ForkJoin、.merge、.concat,但未能实现我要寻找的行为 例如: obs1: Observable<int>; obs2: Observable<Boolean>; save(): Observable<any> { return obs1.concat(obs2); } 或 有没有可能得到这种行为 希望有人能帮忙 编辑: 在我的特定用例中,obs1和ob

我有两个要合并的观测值,它们要么同时使用两个参数,要么只使用一个参数。我尝试了.ForkJoin、.merge、.concat,但未能实现我要寻找的行为

例如:

obs1: Observable<int>;
obs2: Observable<Boolean>;

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

有没有可能得到这种行为

希望有人能帮忙

编辑:

在我的特定用例中,obs1和obs2是两个不同的post请求:obs1是实际的保存函数,obs2检查是否有其他服务正在运行

请求完成后,需要obs1的值来重新加载页面,如果服务正在运行,则需要obs2的值来显示消息-独立于obs1

因此,如果obs2在obs1之前发出,这不是问题,消息将在重新加载之前显示。但是,如果obs1在obs2之前发出,页面将被重新加载,消息可能不再显示

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

您可以使用zip静态方法而不是concat操作符

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

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

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


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

“合并”将以相同的方式发出两个事件,但顺序是它们实际完成的顺序,而不是您所追求的顺序

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

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

CombineTest将在每次发射时发射,因此您将得到类似于[1,4]、[2,4]、[2,5]、[3,5]的结果,具体取决于发射顺序

最后,forkJoin只发出一次,一旦它内部的每个项目都实际完成了,就会发出一次,然后完成它自己。这可能是你最想要的,因为你似乎在存钱。如果这些示例流中的任何一个未完成,forkJoin将永远不会发射,但如果它们都在其最终值之后完成,forkJoin将只给出一个发射:[2,5]。我更喜欢这样,因为这是最安全的操作,因为它保证所有流都正确完成,并且不会造成内存泄漏。通常在保存时,您只需要一次排放,因此它也更明确。当您看到forkJoin时,您就知道您正在处理单个发射流

我个人会这样做:

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函数中真正创建多个参数,因为它的接口只接受一个参数。

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

组合测试 此运算符将组合两个观察值发出的最新值,如大理石图所示:

或者如果要对数组使用反结构

save().subscribe(([val1, val2]) => {
   // Logic
});
最晚从 WithLatestFrom发出由可观察对象发出的最后一个值的组合,请注意,此运算符跳过任何没有来自其他可观察对象的对应值的值

您可以为此目的使用。平行地称呼他们,如果他们中的任何一个在场,那么就做些什么

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
  }
});

您使用的是哪个版本的rxjs?rxjs版本6.1.0可能有用-请参阅此rxjs v6解决方案,该解决方案在subscribe函数上使用zip和param解构-我喜欢两个参数都可见的方式,我可以决定使用一个或两个。@knnhcn是,CombineTest通常是一个安全的选择,当使用数组索引组合多个流时,我看不到变量。因为'zip'返回一个可观察的数组。我使用数组索引语法来提取元素。您排除了最合适的。。。分叉连接。。。如果发射顺序不明确,则withLatestFrom不是一个可行的选项,因为如果第二个源在第一个源之后发射,则其值可能永远不会确定seen@bryan60我没有包括forkJoin,因为它会等到所有的观察对象发出一个onComplete,然后发出最后一个值。然而,对于LatestFrom,它确实会发出当前值,但它可能不会像其他人那样接近答案,因为有其他选择是不会有伤害的。问题显示了一种保存方法,保存方法9/10次都是一次性发射事件,因此为了安全性和明确性,最好使用一次性发射操作符。这也使得WistLatest从一个完全不可行的选项。他尝试了,但没有正确使用它,问题不是他选择的运算符,而是他如何尝试访问值。。。你读了吗
完全是这个问题吗?错误在他的subcribe方法中,他试图以无效的方式访问多个参数。感谢您的回答!我更新了问题,以便进一步澄清。对于当前用例,forkJoin更合适,因为一个ob依赖于另一个ob,而另一个ob不依赖于另一个ob。因此,等待两者解决了时间问题。但是,如果有可能判断obs2可以随时发射而不等待obs1,这将是一个更好的解决方案。forkJoin将等待所有可观测对象发射一个onComplete,并且只发射每个的最后一个值。是。我假设这里我们得到了两个结果,并且根据我们的使用情况使用其中的一个。
obs1$: Observable<int>;
obs2$: Observable<Boolean>;
combined$ = combineLatest(obs1$, obs2$);

combined$.subscribe(([obs1, obs2]) => {
  console.log(obs1);
  console.log(obs2);
})
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
});
obs1: Observable<int>;
obs2: Observable<Boolean>;

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

save().subscribe((val1, val2) => { 
   // logic
});
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
});
save: obs1.pipe(withLatestFrom(secondSource))

save().subscribe(([val1, val2]) => {
    // Logic
});
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
  }
});