withLatestFrom不会发出值

时间:2017-11-01 10:40:15

标签: rxjs

我试图阻止主流,直到使用withLatestFrom运算符和辅助流(包含有关配置状态的信息)初始化配置。

这是我的代码:

@Effect()
public navigationToActiveRedemptionOffers = this.actions$.ofType(ROUTER_NAVIGATION)
  .filter((action: RouterNavigationAction<RouterStateProjection>) => {
    return action.payload.event.url.includes('/redemption-offers/list/active');
  })
  .do(() => console.log('before withLatestFrom'))
  .withLatestFrom(
    this.store.select(selectConfigInitialized)
      .do(initialized => console.log('before config filter', initialized))
      .filter(initialized => initialized)
      .do(initialized => console.log('after config filter', initialized)),
  )
  .do(() => console.log('after withLatestFrom'))
  .switchMap(data => {
    const action = data[0] as RouterNavigationAction<RouterStateProjection>;

    return [
      new MapListingOptionsAction(action.payload.routerState.queryParams),
      new LoadActiveOffersAction(),
    ];
  });

问题是第二个do(在withLatestFrom之后)块永远不会被调用。 经度:

    配置过滤器错误之前
  • 之前withLatestFrom
  • 配置过滤器之前
  • 在config filter true
  • 之后

感谢您的建议。

3 个答案:

答案 0 :(得分:2)

我认为你想要的是.combineLatest

withLatestFrom只会将之前的内容视为触发器。 combineLatest将提供给它的源和可观察对象视为触发器。

所以你的问题是源(路由更改)触发并且传递给withLatest(状态已初始化)的observable由于其过滤器而尚未激活。它只在源触发后发出一个值。所以它被忽略了。

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

const first = Rx.Observable.create((o) => {
  setTimeout(() => {
    o.next();
  }, 2000);
});
const second = Rx.Observable.create((o) => {
  setTimeout(() => {
    o.next(false);
  }, 1000);
  setTimeout(() => {
    o.next(true);
  }, 3000);
});

first
  .do(() => console.log('before withLatestFrom'))
  .withLatestFrom(
    second
      .do(initialized => console.log('before config filter', initialized))
      .filter(initialized => initialized)
      .do(initialized => console.log('after config filter', initialized)),
  )
  .subscribe(() => console.log('after withLatestFrom'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.2/Rx.js"></script>

以下是combineLatest

const first = Rx.Observable.create((o) => {
  setTimeout(() => {
    o.next();
  }, 2000);
});
const second = Rx.Observable.create((o) => {
  setTimeout(() => {
    o.next(false);
  }, 1000);
  setTimeout(() => {
    o.next(true);
  }, 3000);
});

first
  .do(() => console.log('before withLatestFrom'))
  .combineLatest(
    second
      .do(initialized => console.log('before config filter', initialized))
      .filter(initialized => initialized)
      .do(initialized => console.log('after config filter', initialized)),
  )
  .subscribe(() => console.log('after withLatestFrom'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.2/Rx.js"></script>

答案 1 :(得分:1)

withLatestFrom仅在其源Observable发出时才会发出。会发生的事情是this.store.select在源withLatestFrom之前发出。您可以从排放顺序中看到它:

    配置过滤器错误之前
  • 之前使用最新的

  • ...

现在取决于你想要达到的目标。只有当源使用this.store.select(selectConfigInitialized)

发出时,您才能触发concatMap
navigationToActiveRedemptionOffers = this.actions$.ofType(ROUTER_NAVIGATION)
  .filter(...)
  .concatMap(() => this.store.select(selectConfigInitialized)...)
  .switchMap(data => { ... })
  ...

或者您可以传递两个Observables的结果:

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

答案 2 :(得分:0)

通过反转可观察量可以使其更简单。

     protected void Page_Load(object sender, EventArgs e)
            {        
     //whatever you use declarative binding (in aspx page), or define data source  here
                if (!IsPostBack)
                {
                  ddl.DataBind(); //fire databinding events and fill items, and selectedvalue has a value.
                }

                //you can get the selectedvalue
                var sv=ddl.SelectedValue ; //
            }           

由于这是一种常见模式,因此我使用通用public navigationToActiveRedemptionOffers = return this.store.select(selectConfigInitialized) .filter(initialized => initialized) .flatMap(x => return this.actions$.ofType(ROUTER_NAVIGATION) .filter((action: RouterNavigationAction<RouterStateProjection>) => { return action.payload.event.url.includes('/redemption-offers/list/active'); }) .map(action => return [ new MapListingOptionsAction(action.payload.routerState.queryParams), new LoadActiveOffersAction(), ]; ) 方法。

waitFor

用法,

export const waitFor$ = function() {
  return this.filter(data => !!data ).take(1);
};

提供的流利语法
return this.config$
  .waitFor$()
  .flatMap(config => {
    return observableWithRequiredValue()
  }

注意,这种运算符创建方法已被rxjs v5.5中的Lettable Operators取代(但上述方法仍有效)。