Reactjs 如何循环epic呼叫

Reactjs 如何循环epic呼叫,reactjs,react-redux,polling,redux-observable,rxjs6,Reactjs,React Redux,Polling,Redux Observable,Rxjs6,我有以下建议: import { map, catchError, switchMap, takeUntil, } from 'rxjs/operators'; import { FETCH_JOKES, jokesReceived, FETCH_JOKES_CANCELLED, jokesFetchFailed, } from '../actions/jokes-action'; import { ofType } from 'redux-observable'

我有以下建议:

import {
  map,
  catchError,
  switchMap,
  takeUntil,
} from 'rxjs/operators';
import {
  FETCH_JOKES,
  jokesReceived,
  FETCH_JOKES_CANCELLED,
  jokesFetchFailed,
} from '../actions/jokes-action';
import { ofType } from 'redux-observable';
import { of, concat } from 'rxjs';
import { ajax } from 'rxjs/ajax';

const getJokes = () =>
  ajax.getJSON('http://api.icndb.com/jokes/random?escape=javascript');

const fetchJokesEpic = action$ => {
  return action$.pipe(
    ofType(FETCH_JOKES),
    switchMap(() =>
      getJokes().pipe(
        map(response => jokesReceived(response)),
        catchError((err, act) => of(jokesFetchFailed(err))),
        takeUntil(action$.pipe(ofType(FETCH_JOKES_CANCELLED)))
      )
    ),
  );
};

export default fetchJokesEpic;
每当调度
FETCH\u jones
时,此epic将启动
ajax
调用,并在成功调度
joksreceived
操作或失败时
joksfetchfailed

我想循环它,除非取消,否则在上一次调用完成(成功或失败)后将再次调用端点

我想我可以使用另一个epic taht来对收到的
笑话
取回笑话
错误动作做出反应,然后发送
取回笑话
动作,该动作应该再次启动cricle

import { ofType } from 'redux-observable';
import {
  delay,
  map,
} from 'rxjs/operators';
import {
  JOKES_RECEIVED,
  FETCH_JOKES_CANCELLED,
  FETCH_JOKES_ERROR,
  fetchJokes,
} from '../actions/jokes-action';

const pollJokes = (action$, state$) => {
  return action$.pipe(
    ofType(JOKES_RECEIVED, FETCH_JOKES_ERROR, FETCH_JOKES_CANCELLED),
    delay(2000),
    map(action => {
      console.log('pollJokes.map', action);
      if(action.type === FETCH_JOKES_CANCELLED)
      { 
        console.log("Cancelled")
        return { type: 'POLL_STOPPED' };
      }
      else {
        // loop
        return fetchJokes();
      }
    })
  );
};
export default pollJokes;
但是,当我调度
获取\u取消
操作时,这不起作用。操作堆栈如下所示:

@INIT
FETCH_JOKES
JOKES_RECEIVED
FETCH_JOKES
JOKES_RECEIVED
...
FETCH_JOKES_CANCELLED
FETCH_JOKES
JOKES_RECEIVED
POLL_STOPPED
FETCH_JOKES
JOKES_RECEIVED
...
我曾尝试将
takeUntil
添加到
polljones
epic中,但结果同样糟糕

const pollJokes = (action$, state$) => {
  return action$.pipe(
    ofType(JOKES_RECEIVED, FETCH_JOKES_ERROR, FETCH_JOKES_CANCELLED),
    delay(2000),
    map(action => {
      console.log('pollJokes.map', action);
      if(action.type === FETCH_JOKES_CANCELLED)
      { 
        console.log("Cancelled")
        return { type: 'POLL_STOPPED' };
      }
      else {
        // loop
        return fetchJokes();
      }
    }),


    takeUntil(action$.pipe(ofType(FETCH_JOKES_CANCELLED)))


  );
};
使用此方法,
polljones
epic在第一次调度
FETCH\u jones\u CANCELLED
时停止工作。现在我知道史诗是在
takeUntil
上完成的


我该怎么做才能让这个“循环”工作?我想我可以实现一个中间件,当收到
笑话
发送时,它将实际调用
获取笑话
,但我正在搜索一个全rxjs解决方案,

您需要使用
重复
,以便在epic被
取消后重新启动epic

const pollJokes = (action$, state$) => {
  return action$.pipe(
    ofType(JOKES_RECEIVED, FETCH_JOKES_ERROR, FETCH_JOKES_CANCELLED),
    delay(2000),
    map(action => {
      console.log('pollJokes.map', action);
      if(action.type === FETCH_JOKES_CANCELLED)
      { 
        console.log("Cancelled")
        return { type: 'POLL_STOPPED' };
      }
      else {
        // loop
        return fetchJokes();
      }
    }),


    takeUntil(action$.pipe(ofType(FETCH_JOKES_CANCELLED))),
    repeat()

  );
};

的确,这很有帮助,但我相信我已经尝试过:),这个问题还有其他解决方案吗?