制作一个自定义RXJS管道以接受一个可观察对象,并等待该可观察对象满足条件

时间:2019-09-23 21:36:46

标签: angular typescript rxjs rxjs-pipeable-operators

我有以下代码

export function featureReady(feature: BaseFeatureService) {
  return pipe(
    zip(feature.loading$),
    filter(([inputObject, loading]) => !loading),
    map(([inputObject, loading]) => {
      return inputObject;
    })
  );
}

我希望这样食用它。

observable$.pipe(
   featureReady(this.propertyFeatureService)
);
现在不推荐使用

zip代替静态zip,这意味着我的上述解决方案将停止工作,如果有RXJS运算符,我可以将zip运算符或整个解决方案替换为?

对于任何接受等待条件为“可观察”的解决方案,我也将感到满意,因为我不介意传递feature.loading$

谢谢。

2 个答案:

答案 0 :(得分:0)

我环顾了其他运算符,发现withLatestFrom可以用来获得与从上面的zip运算符得到的结果相同的结果。

现在看起来像这样:

export function featureReady(feature: BaseFeatureService) {
  return pipe(
    withLatestFrom(feature.loading$),
    filter(([inputObject, loading]) => !loading),
    map(([inputObject, loading]) => {
      return inputObject;
    })
  );
}

如果有人有更好的解决方案,我将保留问题选项。

答案 1 :(得分:0)

最好使用skipUntil Rxjs管道运算符,该运算符将跳过值,直到内部可观察到的满足ceratin条件为止。

在下面的代码源中,Observable将等待,直到函数fun返回自定义管道,该管道将一直等待,直到可观察的加载状态为false

const { interval, timer,of,concat } = rxjs;
const {  skipUntil,delay,filter,ta } = rxjs.operators;


// Write TypeScript code!
const appDiv = document.getElementById('app');
appDiv.innerHTML = `<h1>Wait until the loading status is false</h1>`;

//custom pipe function which will  until loading
const fun = (wait1) =>  skipUntil(wait1.pipe(filter(status => !status['loading'])));

console.clear()
const status = [{loading:true},{loading:false}]
//emit every 1s
const source = interval(1000);

// inner obserbale which will emit the status after certain interval
const wait1 = concat(of(status[0]).pipe(delay(1000)),of(status[1]).pipe(delay(3000))).pipe(delay(5000));
//skip emitted values from source until inner observable emits false after the loading status turned to false
const example = source.pipe(fun(wait1));

const subscribe = example.subscribe(val => appDiv.innerHTML += 'interval ' + val + '<br/>');
const subscribe1 = wait1.subscribe(val => appDiv.innerHTML += 'inner Observable status ' + val.loading + '<br/>');
<script src="https://unpkg.com/rxjs/bundles/rxjs.umd.min.js"></script>

<div id="app"></div>

您可以找到stackBlitz solution