ngrx effect中如何做http轮询

How to do http polling in ngrx effect

我有这个效果,我正在尝试使用计时器每 x 秒轮询一次数据。但我无法弄清楚计时器应该如何与数据流交互。我尝试将另一个 switchMap 添加到顶部,但是我无法将操作和有效负载传递给第二个 switchmap。有什么想法吗?

我看了,但我的情况有点不同。我正在通过我需要访问的操作传递有效负载,并且我正在使用 ngrx 6。

@Effect()
getData = this.actions$
    .ofType(appActions.GET_PLOT_DATA)
    .pipe(
        switchMap((action$: appActions.GetPlotDataAction) => {
            return this.http.post(
                `http://${this.url}/data`,
                action$.payload.getJson(),
                {responseType: 'json', observe: 'body', headers: this.headers});
        }),
        map((plotData) => {
            return {
                type: appActions.LOAD_DATA_SUCCESS,
                payload: plotData
            }
        }),
        catchError((error) => throwError(error))
    )

这应该有效(我已经测试过了)。请将此添加到 switchMap 的顶部。这里的关键运算符是 mapTo。该运算符会将传入的区间值映射到payload中。

switchMap((action$: appActions.GetPlotDataAction) =>
   interval(5000).pipe(mapTo(action$))
);

更新(提示): 如果您想立即开始轮询,然后每 {n} 毫秒可以使用 startWith 运算符或 timer observable

switchMap((action$: appActions.GetPlotDataAction) =>
  interval(5000).pipe(startWith(0), mapTo(action$))
);

switchMap((action$: appActions.GetPlotDataAction) => 
  timer(0, 1000).pipe(mapTo(action$))
);

更新 (15.04.2021):

例如,使用 takeUntil 和 Subject,您可以在代码中的某处一次停止轮询流,就像这样。当有人点击某物时,您也可以杀死。这取决于您和用例。

const kill$ = new Subject();
switchMap((action$: appActions.GetPlotDataAction) => 
  timer(0, 1000).pipe(mapTo(action$), takeUntil(kill$))
);

// killing for example after 60 seconds
setTimeout(() => kill$.next(), 60000);