RxJS iif参数在不应该被调用的时候被调用

E1-*_*-XP 5 rxjs redux-observable

我想使用RxJS的iif实用程序有条件地调度一些操作。问题是即使测试函数返回false,也会调用iif的第二个参数。这将引发错误,并且应用程序立即崩溃。我对RxJS的功能是陌生的,所以我可能一无所知。如果有问题,我将使用connected-react-router软件包。

导出const roomRouteEpic:Epic =(action $,state $)=>
  action $ .ofType(LOCATION_CHANGE).pipe(
    采摘('payload'),
    mergeMap(有效载荷=>
      iif(
        ()=> {
          console.log('NOT LOGGED');
          返回/^\/room\/\d+$/.test(payload.location.pathname); //设为'/ login'
        },
        合并(
          点击(v => console.log('NOT LOGGED TOO')),
          的(
            //立即评估以下状态值
            state $ .value.rooms.list [payload.location.pathname.split('/')[1]]
              ?actions.rooms.initRoomEnter()
              :actions.rooms.initRoomCreate(),
          ),
          的(actions.global.setIsLoading(true)),
        ),
        empty(),
      ),
    ),
  );

E1-*_*-XP 7

好吧,我自己找到了答案。我的解决方案是完全删除 iif 并仅依赖 mergeMap 中的三元运算符。这样,它不会在每次“LOCATION_CHANGE”之后进行评估,并且只要 regExp 返回 true 即可。感谢您的关注。

export const roomRouteEpic: Epic = (action$, state$) =>
  action$.ofType(LOCATION_CHANGE).pipe(
    pluck<any, any>('payload'),
    mergeMap(payload =>
      /^\/room\/\d+$/.test(payload.location.pathname)
        ? of(
            state$.value.rooms.list[payload.location.pathname.split('/')[2]]
              ? actions.rooms.initRoomEnter()
              : actions.rooms.initRoomCreate(),
            actions.global.setIsLoading(true),
          )
        : EMPTY,
    ),
  );
Run Code Online (Sandbox Code Playgroud)


小智 5

有点迟到了,但我发现的作用,iif不是比其他执行一个路径,而是要订阅一个可观察或其他。也就是说,它将执行获取每个Observable所需的所有代码路径。

从这个例子中...

import { iif, of, pipe } from 'rxjs';
import { mergeMap } from 'rxjs/operators';

const source$ = of('Hello');
const obsOne$ = (x) => {console.log(`${x} World`); return of('One')};
const obsTwo$ = (x) => {console.log(`${x}, Goodbye`); return of('Two')};

source$.pipe(
  mergeMap(v =>
    iif(
      () => v === 'Hello',
      obsOne$(v),
      obsTwo$(v)
    ))
).subscribe(console.log);
Run Code Online (Sandbox Code Playgroud)

您将获得以下输出

Hello World
Hello, Goodbye
One
Run Code Online (Sandbox Code Playgroud)

这是因为,为了得到obsOne$它需要打印Hello World。同样适用于obsTwo$(除了会打印路径Hello, Goodbye)。

但是,您会注意到它仅打印One而不打印Two。这是因为iif评估为true,因此订阅obsOne$

当您进行三元操作时-我发现本文解释了一种更加RxJS驱动的方法,可以很好地实现所需的结果:https ://rangle.io/blog/rxjs-where-is-the-if​​-else-operator/

  • 很好的解释!有一种方法可以解决这个问题,即使用“defer”。因此,如果执行 `iif( condition, defer(() =&gt; obsOne$), defer(() =&gt; obsTwo$))` ,则只会执行与条件相对应的路径。 (11认同)
  • 关于“iif()”执行的很好的解释。 (3认同)