Rxjs withLatestFrom不发出值

Rxjs withLatestFrom不发出值,rxjs,Rxjs,我正在尝试阻止主流,直到使用withLatestFrom操作符和次流(其中包含有关配置状态的信息)初始化配置 这是我的密码: @Effect() public navigationtoactivatedemptionoffers=this.actions$of type(路由器\ U导航) .filter((操作:RouterNavigationAction)=>{ returnaction.payload.event.url.includes('/redemption offers/list/

我正在尝试阻止主流,直到使用
withLatestFrom
操作符和次流(其中包含有关配置状态的信息)初始化配置

这是我的密码:

@Effect()
public navigationtoactivatedemptionoffers=this.actions$of type(路由器\ U导航)
.filter((操作:RouterNavigationAction)=>{
returnaction.payload.event.url.includes('/redemption offers/list/active');
})
.do(()=>console.log('before withLatestFrom'))
.最晚从(
this.store.select(选择ConfigInitialized)
.do(初始化=>console.log('before config filter',initialized))
.filter(已初始化=>已初始化)
.do(初始化=>console.log('after config filter',initialized)),
)
.do(()=>console.log('after withLatestFrom'))
.switchMap(数据=>{
const action=数据[0]作为RouterNavigationAction;
返回[
新的MapListingOptionAction(action.payload.routerState.queryParams),
新建LoadActiveOfferAction(),
];
});
问题是第二个
do
(在
withLatestFrom
之后)块永远不会被调用。 日志:

  • 前配置筛选器为false
  • 从之前到最近
  • 前配置筛选器为true
  • 配置后过滤器为true

谢谢你的建议。

我想你想要的是
.combinelateest

withLatestFrom
只将其前面的内容视为触发器。
CombineTest
将源和提供给它的可观察对象都视为触发器

因此,您的问题是源(路由更改)触发,而传递给带有最新版本的
(state initialized)的
的可观察对象由于其过滤器尚未发出。它仅在源激发后发出值。所以它被忽略了

以下是您正在做的一个运行示例:

const first=Rx.Observable.create((o)=>{
设置超时(()=>{
o、 next();
}, 2000);
});
const second=Rx.Observable.create((o)=>{
设置超时(()=>{
o、 下一个(假);
}, 1000);
设置超时(()=>{
o、 其次(正确);
}, 3000);
});
第一
.do(()=>console.log('before withLatestFrom'))
.最晚从(
第二
.do(初始化=>console.log('before config filter',initialized))
.filter(已初始化=>已初始化)
.do(初始化=>console.log('after config filter',initialized)),
)
.subscribe(()=>console.log('after withLatestFrom'))

只有当其源可观测发射时,才发射带有LatestFrom的
。所发生的情况是,
this.store.select
在源代码之前发出,以
的最新自
。您可以从排放顺序中看到:

  • 前配置筛选器为false

  • 从之前到最近

现在这取决于你想要实现什么。只有当源使用
concatMap发射时,才能触发
this.store.select(选择ConfigInitialized)

navigationToActiveRedemptionOffers = this.actions$.ofType(ROUTER_NAVIGATION)
  .filter(...)
  .concatMap(() => this.store.select(selectConfigInitialized)...)
  .switchMap(data => { ... })
  ...
或者,您可以传递两个观测值的结果:

navigationToActiveRedemptionOffers = this.actions$.ofType(ROUTER_NAVIGATION)
  .filter(...)
  .concatMap(nav => this.store.select(selectConfigInitialized)
    .map(result => [nav, result])
  )
  .switchMap(data => { ... })
  ...

可以通过反转观测值使其更简单

公共导航到活动删除提供程序=
返回此.store.select(选择ConfigInitialized)
.filter(已初始化=>已初始化)
.flatMap(x=>
返回此类型的.actions$(路由器导航)
.filter((操作:RouterNavigationAction)=>{
returnaction.payload.event.url.includes('/redemption offers/list/active');
})
.map(操作=>
返回[
新的MapListingOptionAction(action.payload.routerState.queryParams),
新建LoadActiveOfferAction(),
];
)
因为这是一种常见的模式,所以我使用了一个通用的
waitFor
方法

export const waitFor$=函数(){
返回此.filter(数据=>!!数据)。获取(1);
};
用法

返回this.config$
.waitFor$()
.flatMap(配置=>{
返回observableWithRequiredValue()
}
由提供的流畅语法

Observable.prototype.waitFor$=waitFor$;
声明模块“rxjs/Observable”{
可观测界面{
waitFor$:waitFor$的类型;
}
}

注意,这种操作符创建方法已经被rxjs v5.5所取代(但上面的方法仍然有效)。

谢谢,
CombineTest
操作符工作得很好。可能我误解了
与最新的
文档:“所有输入观察对象必须发出至少一个值,然后输出观察对象才会发出一个值。”RxJS的文档只需做一些小的工作就可以做得更好。它们需要提供示例用例,而不仅仅是一系列发出计时器。我已经使用CombineTest的静态版本有一段时间了,当withLatestFrom什么都没做时,我感到非常困惑——特别是因为我曾经订阅过just一个console.log命令,该命令在删除时破坏了它。